t_vp_build.c revision dba21ed913da2222e3b55fc8ba724ca93acbabf1
1f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* 2f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Mesa 3-D graphics library 3de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul * Version: 6.5 4f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 5564b2aa2ef8d5b859bb51d39024373a4865e93e9Brian Paul * Copyright (C) 2006 Tungsten Graphics All Rights Reserved. 6f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 7f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * copy of this software and associated documentation files (the "Software"), 9f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * to deal in the Software without restriction, including without limitation 10f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Software is furnished to do so, subject to the following conditions: 13f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 14f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * The above copyright notice and this permission notice shall be included 15f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * in all copies or substantial portions of the Software. 16f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 17f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * WHETHER IN 22f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 25f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 26f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/** 27f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * \file t_vp_build.c 28f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Create a vertex program to execute the current fixed function T&L pipeline. 29f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * \author Keith Whitwell 30f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 31f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 32f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 33f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "glheader.h" 34f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "macros.h" 35f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "enums.h" 3660a7200c0de7fc2925430b466739b4021087d14cBrian Paul#include "program.h" 3760a7200c0de7fc2925430b466739b4021087d14cBrian Paul#include "prog_instruction.h" 3860a7200c0de7fc2925430b466739b4021087d14cBrian Paul#include "prog_parameter.h" 3960a7200c0de7fc2925430b466739b4021087d14cBrian Paul#include "prog_print.h" 4060a7200c0de7fc2925430b466739b4021087d14cBrian Paul#include "prog_statevars.h" 410c6723aee564a7b320ca122c3c9b003c863cc714Brian Paul#include "t_context.h" /* NOTE: very light dependency on this */ 42f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_vp_build.h" 43f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 44f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 45a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstruct state_key { 46a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_global_enabled:1; 47a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_local_viewer:1; 48a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_twoside:1; 49a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_color_material:1; 50a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_color_material_mask:12; 51a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_material_mask:12; 52a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 53a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned normalize:1; 54a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned rescale_normals:1; 55a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned fog_source_is_depth:1; 56a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned tnl_do_vertex_fog:1; 57a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned separate_specular:1; 58a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned fog_mode:2; 59a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned point_attenuated:1; 601c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell unsigned texture_enabled_global:1; 61c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell unsigned fragprog_inputs_read:12; 62a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 63a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct { 64a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_enabled:1; 65a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_eyepos3_is_zero:1; 66a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_spotcutoff_is_180:1; 67a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_attenuated:1; 68a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texunit_really_enabled:1; 69a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texmat_enabled:1; 70a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_enabled:4; 71a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode0:4; 72a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode1:4; 73a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode2:4; 74a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode3:4; 75a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } unit[8]; 76a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell}; 77a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 78a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 79a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 80c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_NONE 0 81c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_LINEAR 1 82c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_EXP 2 83c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_EXP2 3 84a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 85a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 86a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 87a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (mode) { 88a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 89a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EXP: return FOG_EXP; 90a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EXP2: return FOG_EXP2; 91c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell default: return FOG_NONE; 92a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 93a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 94a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 95a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_NONE 0 96a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_OBJ_LINEAR 1 97a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_EYE_LINEAR 2 98a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_SPHERE_MAP 3 99a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_REFLECTION_MAP 4 100a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_NORMAL_MAP 5 101a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 102a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint translate_texgen( GLboolean enabled, GLenum mode ) 103a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 104a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!enabled) 105a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return TXG_NONE; 106a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 107a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (mode) { 108a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_OBJECT_LINEAR: return TXG_OBJ_LINEAR; 109a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EYE_LINEAR: return TXG_EYE_LINEAR; 110a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_SPHERE_MAP: return TXG_SPHERE_MAP; 111a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_REFLECTION_MAP_NV: return TXG_REFLECTION_MAP; 112a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_NORMAL_MAP_NV: return TXG_NORMAL_MAP; 113a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell default: return TXG_NONE; 114a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 115a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 116a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 117a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic struct state_key *make_state_key( GLcontext *ctx ) 118a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 119a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 120a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct vertex_buffer *VB = &tnl->vb; 121122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 122a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct state_key *key = CALLOC_STRUCT(state_key); 123a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint i; 124a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 125c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* This now relies on texenvprogram.c being active: 126c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 127c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell assert(fp); 128c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 129de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul key->fragprog_inputs_read = fp->Base.InputsRead; 130c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 131a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->separate_specular = (ctx->Light.Model.ColorControl == 132a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GL_SEPARATE_SPECULAR_COLOR); 133a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 134a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Enabled) { 135a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_global_enabled = 1; 136a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 137a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Model.LocalViewer) 138a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_local_viewer = 1; 139a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 140a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Model.TwoSide) 141a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_twoside = 1; 142a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 143f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell if (ctx->Light.ColorMaterialEnabled) { 144a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_color_material = 1; 145f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell key->light_color_material_mask = ctx->Light.ColorMaterialBitmask; 146f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell } 147a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 14894b30dc390f1fdd526c080080830016fad3e2ee2Brian Paul for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) 149a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (VB->AttribPtr[i]->stride) 150f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell key->light_material_mask |= 1<<(i-_TNL_ATTRIB_MAT_FRONT_AMBIENT); 151a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 152a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 153a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct gl_light *light = &ctx->Light.Light[i]; 154a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 155a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->Enabled) { 156a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_enabled = 1; 157a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 158a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->EyePosition[3] == 0.0) 159a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_eyepos3_is_zero = 1; 160a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 161a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->SpotCutoff == 180.0) 162a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_spotcutoff_is_180 = 1; 163a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 164a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->ConstantAttenuation != 1.0 || 165729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell light->LinearAttenuation != 0.0 || 166729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell light->QuadraticAttenuation != 0.0) 167a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_attenuated = 1; 168a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 169a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 170a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 171a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 172a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Transform.Normalize) 173a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->normalize = 1; 174f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 175a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Transform.RescaleNormals) 176a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->rescale_normals = 1; 177a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 178c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key->fog_mode = translate_fog_mode(fp->FogOption); 179c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 180c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) 181c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key->fog_source_is_depth = 1; 182c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 183c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (tnl->_DoVertexFog) 184c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key->tnl_do_vertex_fog = 1; 185a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 186a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Point._Attenuated) 187a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->point_attenuated = 1; 188a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1891c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell if (ctx->Texture._TexGenEnabled || 1901c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell ctx->Texture._TexMatEnabled || 1911c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell ctx->Texture._EnabledUnits) 1921c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell key->texture_enabled_global = 1; 1931c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell 194a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 195a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 196a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 197a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (texUnit->_ReallyEnabled) 198a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texunit_really_enabled = 1; 199a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 200a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) 201a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texmat_enabled = 1; 202a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 203a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (texUnit->TexGenEnabled) { 204a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_enabled = 1; 205a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 206a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode0 = 207a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<0), 208a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeS ); 209a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode1 = 210a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<1), 211a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeT ); 212a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode2 = 213a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<2), 214a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeR ); 215a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode3 = 216a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<3), 217a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeQ ); 218a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 219a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 220a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 221a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return key; 222a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 223a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 224a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 225a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 226f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Very useful debugging tool - produces annotated listing of 227f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * generated program with line/function references for each 228f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * instruction back into this file: 229f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 230729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell#define DISASSEM (MESA_VERBOSE&VERBOSE_DISASSEM) 23110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 23210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell/* Should be tunable by the driver - do we want to do matrix 23310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell * multiplications with DP4's or with MUL/MAD's? SSE works better 23410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell * with the latter, drivers may differ. 23510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 236a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define PREFER_DP4 0 237f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 238821b3dd562c0ec4560e50f29084c32653cf18c9dAapo Tahkola#define MAX_INSN 256 2392fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell 240f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Use uregs to represent registers internally, translate to Mesa's 241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * expected formats on emit. 242f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * NOTE: These are passed by value extensively in this file rather 244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * than as usual by pointer reference. If this disturbs you, try 245f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * remembering they are just 32bits in size. 246f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 247f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * GCC is smart enough to deal with these dword-sized structures in 248f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * much the same way as if I had defined them as dwords and was using 249f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * macros to access and set the fields. This is much nicer and easier 250f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * to evolve. 251f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 252f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct ureg { 253f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint file:4; 25461e694f270d8a4a03a3245b5e6eea805915ed74bBrian Paul GLint idx:8; /* relative addressing may be negative */ 255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint negate:1; 256f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint swz:12; 257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint pad:7; 258f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 259f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 261f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct tnl_program { 262a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const struct state_key *state; 263122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_vertex_program *program; 264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 2653509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell GLuint temp_in_use; 266f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint temp_reserved; 267f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 268f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position; 269f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position_normalized; 270f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_normal; 271f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg identity; 272f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 273f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint materials; 274f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint color_materials; 275f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 276f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 277f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 278564b2aa2ef8d5b859bb51d39024373a4865e93e9Brian Paulstatic const struct ureg undef = { 279a89b099c74c0129c975d3f7ba1cdccc6a8d6b6beAlan Hourihane PROGRAM_UNDEFINED, 280f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell ~0, 281f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 283f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0 284f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 285f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 286f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Local shorthand: 287f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 288f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define X SWIZZLE_X 289f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Y SWIZZLE_Y 290f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Z SWIZZLE_Z 291f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define W SWIZZLE_W 292f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 293f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 294f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Construct a ureg: 295f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 29660a6a0eb51a6cafc9f65bff8028510e0788cf311Brian Paulstatic struct ureg make_ureg(GLuint file, GLint idx) 297f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 298f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg; 299f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.file = file; 300f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.idx = idx; 301f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate = 0; 302f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = SWIZZLE_NOOP; 303f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.pad = 0; 304f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 305f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 306f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 307f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 309f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg negate( struct ureg reg ) 310f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 311f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate ^= 1; 312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 314f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 315f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 319f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, y), 320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, z), 321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, w)); 322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 324f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return swizzle(reg, x, x, x, x); 329f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 330f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 331f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_temp( struct tnl_program *p ) 332f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 333b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul int bit = _mesa_ffs( ~p->temp_in_use ); 334f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!bit) { 335b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 336b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 337f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 338f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 339564b2aa2ef8d5b859bb51d39024373a4865e93e9Brian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 340c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->program->Base.NumTemporaries = bit; 341c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 3423509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use |= 1<<(bit-1); 343f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_TEMPORARY, bit-1); 344f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 345f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 346f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg reserve_temp( struct tnl_program *p ) 347f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 348f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp( p ); 349f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_reserved |= 1<<temp.idx; 350f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 351f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 352f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 353f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temp( struct tnl_program *p, struct ureg reg ) 354f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY) { 3563509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use &= ~(1<<reg.idx); 3573509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use |= p->temp_reserved; /* can't release reserved temps */ 358f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temps( struct tnl_program *p ) 362f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 3633509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use = p->temp_reserved; 364f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 365f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 366f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 367f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 368f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_input( struct tnl_program *p, GLuint input ) 369f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 370de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p->program->Base.InputsRead |= (1<<input); 371f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_INPUT, input); 372f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 373f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 374f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_output( struct tnl_program *p, GLuint output ) 375f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 376de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p->program->Base.OutputsWritten |= (1<<output); 377f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_OUTPUT, output); 378f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 379f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 380f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_const4f( struct tnl_program *p, 381f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s0, 382f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s1, 383f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s2, 384f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s3) 385f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 386f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat values[4]; 38760a6a0eb51a6cafc9f65bff8028510e0788cf311Brian Paul GLint idx; 388a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul GLuint swizzle; 389f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[0] = s0; 390f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[1] = s1; 391f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[2] = s2; 392f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[3] = s3; 393a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, 394a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul &swizzle ); 395a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ASSERT(swizzle == SWIZZLE_NOOP); 396f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 397f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 398f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 399f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 40096582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 401f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 402f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 403f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 404f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLboolean is_undef( struct ureg reg ) 405f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 406a89b099c74c0129c975d3f7ba1cdccc6a8d6b6beAlan Hourihane return reg.file == PROGRAM_UNDEFINED; 407f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 408f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 409f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_identity_param( struct tnl_program *p ) 410f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 411f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->identity)) 412f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->identity = register_const4f(p, 0,0,0,1); 413f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 414f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->identity; 415f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 416f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 417fce8409cbbe6aa5309163f3d63894233b8833308Brian Paulstatic struct ureg register_param5(struct tnl_program *p, 418f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s0, 419f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s1, 420f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s2, 421f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s3, 422fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s4) 423f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 424fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul gl_state_index tokens[STATE_LENGTH]; 42560a6a0eb51a6cafc9f65bff8028510e0788cf311Brian Paul GLint idx; 426f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[0] = s0; 427f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[1] = s1; 428f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[2] = s2; 429f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[3] = s3; 430f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[4] = s4; 431de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); 432f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 433f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 434f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 435f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 436fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) 437fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) 438fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) 439fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) 440f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 441f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 442fce8409cbbe6aa5309163f3d63894233b8833308Brian Paulstatic void register_matrix_param5( struct tnl_program *p, 443fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s0, /* modelview, projection, etc */ 444fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s1, /* texture matrix number */ 445fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s2, /* first row */ 446fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s3, /* last row */ 447fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s4, /* inverse, transpose, etc */ 448f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg *matrix ) 449f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 450564b2aa2ef8d5b859bb51d39024373a4865e93e9Brian Paul GLint i; 451f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 452f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* This is a bit sad as the support is there to pull the whole 453f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * matrix out in one go: 454f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 455fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul for (i = 0; i <= s3 - s2; i++) 456fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul matrix[i] = register_param5( p, s0, s1, i, i, s4 ); 457f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 458f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 459f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 4607e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_arg( struct prog_src_register *src, 461f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg ) 462f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 463f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->File = reg.file; 464f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Index = reg.idx; 465f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Swizzle = reg.swz; 46616d1024f27695bd9ceb86ffcdda960396a23ed2cAapo Tahkola src->NegateBase = reg.negate ? NEGATE_XYZW : 0; 4677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul src->Abs = 0; 4687e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul src->NegateAbs = 0; 469f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->RelAddr = 0; 470f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 471f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 4727e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_dst( struct prog_dst_register *dst, 473f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg, GLuint mask ) 474f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 475f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->File = reg.file; 476f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->Index = reg.idx; 4775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* allow zero as a shorthand for xyzw */ 4785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell dst->WriteMask = mask ? mask : WRITEMASK_XYZW; 4797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul dst->CondMask = COND_TR; 4807e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul dst->CondSwizzle = 0; 4817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul dst->CondSrc = 0; 482f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->pad = 0; 483f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 484f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 4857e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void debug_insn( struct prog_instruction *inst, const char *fn, 4865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint line ) 487f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 488729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell if (DISASSEM) { 489729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell static const char *last_fn; 490f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 491729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell if (fn != last_fn) { 492729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell last_fn = fn; 493729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell _mesa_printf("%s:\n", fn); 494729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell } 495f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 496729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell _mesa_printf("%d:\t", line); 497de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul _mesa_print_instruction(inst); 498729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell } 499f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 500f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 501f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 502f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_op3fn(struct tnl_program *p, 503f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint op, 504f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 505f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint mask, 506f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src0, 507f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src1, 508f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src2, 509f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const char *fn, 510f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint line) 511f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 512f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr = p->program->Base.NumInstructions++; 513de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 514f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5152fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell if (p->program->Base.NumInstructions > MAX_INSN) { 516a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_problem(0, "Out of instructions in emit_op3fn\n"); 5172fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell return; 5182fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell } 5192fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell 5209580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul inst->Opcode = (enum prog_opcode) op; 521dbeea25bb834479a29712100888c862348112018Keith Whitwell inst->StringPos = 0; 522dbeea25bb834479a29712100888c862348112018Keith Whitwell inst->Data = 0; 523f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 524f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 525f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 526f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 527f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 528f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_dst( &inst->DstReg, dest, mask ); 529f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 530f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell debug_insn(inst, fn, line); 531f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 532f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 533f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op3(p, op, dst, mask, src0, src1, src2) \ 5355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__) 5365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op2(p, op, dst, mask, src0, src1) \ 5385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__) 5395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op1(p, op, dst, mask, src0) \ 5415f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__) 542f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 543f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 544f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_temp( struct tnl_program *p, struct ureg reg ) 545f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 546f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY && 547f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell !(p->temp_reserved & (1<<reg.idx))) 548f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 549f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 550f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp(p); 5517e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, temp, 0, reg); 552f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 553f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 554f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 555f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 556f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 557f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Currently no tracking performed of input/output/register size or 558f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * active elements. Could be used to reduce these operations, as 559f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * could the matrix type. 560f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 561f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec4( struct tnl_program *p, 562f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 563f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 564f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 565f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 5667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]); 5677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]); 5687e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]); 5697e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]); 5705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 5715f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 57247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell/* This version is much easier to implement if writemasks are not 57347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * supported natively on the target or (like SSE), the target doesn't 57447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * have a clean/obvious dotproduct implementation. 57547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 5765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void emit_transpose_matrix_transform_vec4( struct tnl_program *p, 5775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 5785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell const struct ureg *mat, 5795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg src) 5805f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 5815f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp; 5825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell if (dest.file != PROGRAM_TEMPORARY) 5845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell tmp = get_temp(p); 5855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell else 5865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell tmp = dest; 587f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); 5897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); 5907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); 5917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); 5925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5935f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell if (dest.file != PROGRAM_TEMPORARY) 5945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, tmp); 595f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 596f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 597f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec3( struct tnl_program *p, 598f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 599f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 600f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 601f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 6027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]); 6037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]); 6047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]); 605f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 606f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 607f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 608f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_normalize_vec3( struct tnl_program *p, 609f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 610f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src ) 611f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 612f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 6137e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, src, src); 6147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); 6157e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, dest, 0, src, tmp); 616f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 617f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 618f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 61910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwellstatic void emit_passthrough( struct tnl_program *p, 62010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell GLuint input, 62110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell GLuint output ) 62210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell{ 62310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg out = register_output(p, output); 6247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out, 0, register_input(p, input)); 62510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell} 62610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 627f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position( struct tnl_program *p ) 628f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 629f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position)) { 630f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 631f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg modelview[4]; 632f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 633f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position = reserve_temp(p); 634f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 63510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 636fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 637fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul 0, modelview ); 63810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 63910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); 64010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 64110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 642fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 64310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX_TRANSPOSE, modelview ); 64410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 64510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); 64610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 647f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 648f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 649f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position; 650f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 651f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 652f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 653f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position_normalized( struct tnl_program *p ) 654f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 655f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position_normalized)) { 656f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 657f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position_normalized = reserve_temp(p); 658f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, p->eye_position_normalized, eye); 659f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 660f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 661f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position_normalized; 662f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 663f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 664f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 665f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_normal( struct tnl_program *p ) 666f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 667f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_normal)) { 668f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); 669f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvinv[3]; 670f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 671fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2, 6725f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_MATRIX_INVTRANS, mvinv ); 673f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 674f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_normal = reserve_temp(p); 675f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 676f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Transform to eye space: 677f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 678f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal ); 679f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 680f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Normalize/Rescale: 681f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 682a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->normalize) { 683f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3( p, p->eye_normal, p->eye_normal ); 684f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 685a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell else if (p->state->rescale_normals) { 6865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg rescale = register_param2(p, STATE_INTERNAL, 6875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_NORMAL_SCALE); 6885f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 6897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2( p, OPCODE_MUL, p->eye_normal, 0, normal, 6905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell swizzle1(rescale, X)); 691f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 692f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 693f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 694f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_normal; 695f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 696f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 697f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 698f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 699f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_hpos( struct tnl_program *p ) 700f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 701f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 702f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); 703f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvp[4]; 704f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 70510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 706fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 707fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul 0, mvp ); 70810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, hpos, mvp, pos ); 70910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 71010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 711fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 71210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX_TRANSPOSE, mvp ); 71310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); 71410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 715f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 716f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 717f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 718f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLuint material_attrib( GLuint side, GLuint property ) 719f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 720f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell return ((property - STATE_AMBIENT) * 2 + 7215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell side); 722f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 723f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 724c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell/* Get a bitmask of which material values vary on a per-vertex basis. 725c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 726f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void set_material_flags( struct tnl_program *p ) 727f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 728f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->color_materials = 0; 729f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 0; 730f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 731a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_color_material) { 732f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 733a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->color_materials = p->state->light_color_material_mask; 734f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 735f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 736a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->materials |= p->state->light_material_mask; 737f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 738f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 739f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 7405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_material( struct tnl_program *p, GLuint side, 7415f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint property ) 742f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 743f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 744f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 745f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->color_materials & (1<<attrib)) 746f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_input(p, VERT_ATTRIB_COLOR0); 747f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else if (p->materials & (1<<attrib)) 748f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell return register_input( p, attrib + _TNL_ATTRIB_MAT_FRONT_AMBIENT ); 749f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 750f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param3( p, STATE_MATERIAL, side, property ); 751f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 752f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 753f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell#define SCENE_COLOR_BITS(side) (( MAT_BIT_FRONT_EMISSION | \ 754f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell MAT_BIT_FRONT_AMBIENT | \ 755f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell MAT_BIT_FRONT_DIFFUSE) << (side)) 756f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 757f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Either return a precalculated constant value or emit code to 758f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * calculate these values dynamically in the case where material calls 759f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * are present between begin/end pairs. 760f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 761f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Probably want to shift this to the program compilation phase - if 762f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * we always emitted the calculation here, a smart compiler could 763f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * detect that it was constant (given a certain set of inputs), and 764f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * lift it out of the main loop. That way the programs created here 765f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * would be independent of the vertex_buffer details. 766f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 767f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) 768f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 769f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & SCENE_COLOR_BITS(side)) { 7705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); 771f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_emission = get_material(p, side, STATE_EMISSION); 772f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); 773f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); 774f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = make_temp(p, material_diffuse); 7757e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, 7765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell material_ambient, material_emission); 777f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 778f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 779f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 780f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side ); 781f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 782f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 783f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 7845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_lightprod( struct tnl_program *p, GLuint light, 7855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint side, GLuint property ) 786f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 787f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 788f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & (1<<attrib)) { 7895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg light_value = 7905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_param3(p, STATE_LIGHT, light, property); 791f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_value = get_material(p, side, property); 792f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 7937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, tmp, 0, light_value, material_value); 794f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 795f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 796f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 797f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param4(p, STATE_LIGHTPROD, light, side, property); 798f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 799f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 8005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg calculate_light_attenuation( struct tnl_program *p, 8015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint i, 8025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg VPpli, 8035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dist ) 8045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 8055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg attenuation = register_param3(p, STATE_LIGHT, i, 8065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_ATTENUATION); 8075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg att = get_temp(p); 8085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8095f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Calculate spot attenuation: 8105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 811a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180) { 81254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger struct ureg spot_dir_norm = register_param3(p, STATE_INTERNAL, 81354dac2c84310536cce962101de29546d3eb80175Roland Scheidegger STATE_SPOT_DIR_NORMALIZED, i); 8145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg spot = get_temp(p); 8155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg slt = get_temp(p); 81654dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 81754dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm); 81854dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot); 8197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); 8207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, att, 0, slt, spot); 8215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, spot); 8235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, slt); 8245f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8255f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Calculate distance attenuation: 8275f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 828a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_attenuated) { 8295f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/d,d,d,1/d */ 8317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RCP, dist, WRITEMASK_YZ, dist); 8325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1,d,d*d,1/d */ 8337e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, dist, WRITEMASK_XZ, dist, swizzle1(dist,Y)); 8345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/dist-atten */ 8357e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dist, 0, attenuation, dist); 8365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 837a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180) { 8385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* dist-atten */ 8397e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RCP, dist, 0, dist); 8405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* spot-atten * dist-atten */ 8417e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, att, 0, dist, att); 8425f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } else { 8435f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* dist-atten */ 8447e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RCP, att, 0, dist); 8455f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8465f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8475f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8485f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell return att; 8495f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 8505f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8515f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 852f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 853f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 854f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 855f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Need to add some addtional parameters to allow lighting in object 85623d31efc167f09d47635352f697ffcb087d3ebbdBrian Paul * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye 857f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space lighting. 858f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 859f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_lighting( struct tnl_program *p ) 860f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 861a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const GLboolean twoside = p->state->light_twoside; 862a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const GLboolean separate = p->state->separate_specular; 863f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr_lights = 0, count = 0; 864f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 865f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg lit = get_temp(p); 866f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dots = get_temp(p); 867f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _col0 = undef, _col1 = undef; 868f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _bfc0 = undef, _bfc1 = undef; 869f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i; 870f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 871f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) 872a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_enabled) 873f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell nr_lights++; 874f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 875f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell set_material_flags(p); 876f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 877f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 878f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 0, STATE_SHININESS); 8797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); 880f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 881f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 882f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col0 = make_temp(p, get_scenecolor(p, 0)); 883f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 884f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = make_temp(p, get_identity_param(p)); 885f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 886f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = _col0; 887f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 888f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 889f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 890f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 891f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 1, STATE_SHININESS); 8927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, 8935f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell negate(swizzle1(shininess,X))); 894f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 895f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 896f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc0 = make_temp(p, get_scenecolor(p, 1)); 897f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 898f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = make_temp(p, get_identity_param(p)); 899f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 900f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = _bfc0; 901f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 902f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 90310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 90410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell /* If no lights, still need to emit the scenecolor. 90510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 90610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell { 90710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); 9087e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res0, 0, _col0); 90910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 91010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 91110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (separate) { 91210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); 9137e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res1, 0, _col1); 91410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 91510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 91610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside) { 91710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); 9187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); 91910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 92010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 92110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside && separate) { 92210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); 9237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); 92410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 92510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 926f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell if (nr_lights == 0) { 92710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell release_temps(p); 92810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell return; 92910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 93010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 93110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 932f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 933a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_enabled) { 934f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg half = undef; 935f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg att = undef, VPpli = undef; 936f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 937f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell count++; 938f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 939a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_eyepos3_is_zero) { 94047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Can used precomputed constants in this case. 94147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * Attenuation never applies to infinite lights. 942f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9435f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell VPpli = register_param3(p, STATE_LIGHT, i, 9445f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION_NORMALIZED); 94561ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao if (p->state->light_local_viewer) { 94661ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao struct ureg eye_hat = get_eye_position_normalized(p); 94761ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao half = get_temp(p); 94861ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); 94961ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao emit_normalize_vec3(p, half, half); 95061ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao } else { 95123d31efc167f09d47635352f697ffcb087d3ebbdBrian Paul half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR); 95261ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao } 953f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 954f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 9555f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg Ppli = register_param3(p, STATE_LIGHT, i, 9565f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION); 957f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg V = get_eye_position(p); 9585f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dist = get_temp(p); 959f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 960f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell VPpli = get_temp(p); 961f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell half = get_temp(p); 962f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 963f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calulate VPpli vector 964f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); 966f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 9675f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Normalize VPpli. The dist value also used in 968f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * attenuation below. 969f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9707e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli); 9717e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RSQ, dist, 0, dist); 9727e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist); 973f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 974f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 975f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate attenuation: 976f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 977a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180 || 978a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->state->unit[i].light_attenuated) { 979a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell att = calculate_light_attenuation(p, i, VPpli, dist); 980f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 981f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 982f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 983f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate viewer direction, or use infinite viewer: 984f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 985a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_local_viewer) { 986f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 9877e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); 988f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 989f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 9905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); 9917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir); 992f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 993f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 994f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, half, half); 995f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 9965f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, dist); 997f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 998f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 999f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate dot products: 1000f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 10017e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); 10027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); 1003f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1004f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1005f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Front face lighting: 1006f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1007f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 1008f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); 1009f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); 1010f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); 1011f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 1012f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell GLuint mask0, mask1; 1013f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_LIT, lit, 0, dots); 1015f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1016f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 10177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 1018f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 101947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1020f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1021f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1022f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = WRITEMASK_XYZ; 1023f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1024f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_COL0 ); 1025f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL1 ); 1026f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1027f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1028f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1029f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1030f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1031f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL0 ); 1032f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1033f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1034f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1035f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = 0; 1036f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1037f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _col1; 1038f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1039f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10407e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); 10417e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0); 10427e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1); 1043f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1044f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1045f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1046f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1047f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1048f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1049f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Back face lighting: 1050f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1051f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 1052f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); 1053f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); 1054f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); 1055f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 1056f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell GLuint mask0, mask1; 1057f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10587e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_LIT, lit, 0, negate(swizzle(dots,X,Y,W,Z))); 1059f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1060f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 10617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 1062f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1063f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1064f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1065f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = WRITEMASK_XYZ; 1066f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1067f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_BFC0 ); 1068f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC1 ); 1069f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1070f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1071f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1072f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1073f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1074f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC0 ); 1075f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1076f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1077f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1078f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _bfc1; 1079f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1080f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = 0; 1081f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1082f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10837e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); 10847e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); 10857e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); 1086f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1087f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1088f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1089f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1090f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1091f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1092f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, half); 1093f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, VPpli); 1094f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, att); 1095f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1096f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1097f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1098f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps( p ); 1099f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1100f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1101f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1102f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_fog( struct tnl_program *p ) 1103f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1104f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg fog = register_output(p, VERT_RESULT_FOGC); 1105f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg input; 11065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 1107a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->fog_source_is_depth) { 1108f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(get_eye_position(p), Z); 1109f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1110f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1111f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); 1112f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1113f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1114a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->tnl_do_vertex_fog) { 111599dfca1e7fb32157135511bded07376ebb25acb3Roland Scheidegger struct ureg params = register_param2(p, STATE_INTERNAL, 111699dfca1e7fb32157135511bded07376ebb25acb3Roland Scheidegger STATE_FOG_PARAMS_OPTIMIZED); 1117f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 1118f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1119a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (p->state->fog_mode) { 1120a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_LINEAR: { 1121f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg id = get_identity_param(p); 112254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op3(p, OPCODE_MAD, tmp, 0, input, swizzle1(params,X), swizzle1(params,Y)); 11237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ 11247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); 1125f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1126f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1127a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP: 11287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_ABS, tmp, 0, input); 112954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z)); 113054dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); 1131f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1132a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP2: 113354dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); 11347e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); 113554dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); 1136f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1137f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1138f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1139f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 1140f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1141f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1142f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* results = incoming fog coords (compute fog per-fragment later) 1143f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 1144f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * KW: Is it really necessary to do anything in this case? 1145f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 11467e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input); 1147f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1148f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 11495f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11505f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_reflect_texgen( struct tnl_program *p, 11515f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 11525f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 11535f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 11545f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 11555f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 11565f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 1157f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 11585f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 11597e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 11605f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 11617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 11625f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 11637e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, writemask, negate(tmp), normal, eye_hat); 1164ab377ce414ba5ca286bab0ddc8e80769bcb88656Keith Whitwell 1165ab377ce414ba5ca286bab0ddc8e80769bcb88656Keith Whitwell release_temp(p, tmp); 11665f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 11675f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11685f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_sphere_texgen( struct tnl_program *p, 11695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 11705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 11715f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 11725f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 11735f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 11745f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 117596582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell struct ureg half = register_scalar_const(p, .5); 11765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg r = get_temp(p); 11775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg inv_m = get_temp(p); 11785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg id = get_identity_param(p); 11795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11805f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Could share the above calculations, but it would be 11815f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * a fairly odd state for someone to set (both sphere and 11825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflection active for different texture coordinate 11835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * components. Of course - if two texture units enable 11845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflect and/or sphere, things start to tilt in favour 11855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * of seperating this out: 11865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 11875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11885f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 11897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 11905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 11917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 11925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 11937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat); 11945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r + 0,0,1 */ 11957e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, r, swizzle(id,X,Y,W,Z)); 11965f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* rx^2 + ry^2 + (rz+1)^2 */ 11977e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, tmp, tmp); 11985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2/m */ 11997e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); 12005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/m */ 12017e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, inv_m, 0, tmp, half); 12025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r/m + 1/2 */ 12037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, writemask, r, inv_m, half); 12045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, tmp); 12065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, r); 12075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, inv_m); 12085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 1209f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1210f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1211f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_texture_transform( struct tnl_program *p ) 1212f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1213f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i, j; 1214f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1215a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 1216f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1217e713c21bd09468887faceebcba9a62a406321c07Brian Paul if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i))) 1218c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell continue; 1219c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1220c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->unit[i].texgen_enabled || 1221c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->state->unit[i].texmat_enabled) { 1222c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1223c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell GLuint texmat_enabled = p->state->unit[i].texmat_enabled; 122410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); 1225f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg out_texgen = undef; 1226f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1227a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].texgen_enabled) { 1228f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint copy_mask = 0; 1229f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint sphere_mask = 0; 1230f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint reflect_mask = 0; 1231f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint normal_mask = 0; 1232f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint modes[4]; 1233f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1234f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) 1235f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = get_temp(p); 1236f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 1237f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = out; 1238f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1239a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[0] = p->state->unit[i].texgen_mode0; 1240a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[1] = p->state->unit[i].texgen_mode1; 1241a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[2] = p->state->unit[i].texgen_mode2; 1242a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[3] = p->state->unit[i].texgen_mode3; 1243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (j = 0; j < 4; j++) { 1245a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (modes[j]) { 1246a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_OBJ_LINEAR: { 1247a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg obj = register_input(p, VERT_ATTRIB_POS); 1248a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1249a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1250a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_OBJECT_S + j); 1251a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 12527e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1253a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell obj, plane ); 1254a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1256a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_EYE_LINEAR: { 1257a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg eye = get_eye_position(p); 1258a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1259a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1260a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_EYE_S + j); 1261a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 12627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1263a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell eye, plane ); 1264a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1265a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1266a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_SPHERE_MAP: 1267a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell sphere_mask |= WRITEMASK_X << j; 1268a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1269a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_REFLECTION_MAP: 1270a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell reflect_mask |= WRITEMASK_X << j; 1271a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1272a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NORMAL_MAP: 1273a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell normal_mask |= WRITEMASK_X << j; 1274a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1275a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NONE: 1276f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell copy_mask |= WRITEMASK_X << j; 1277a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1278a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1279f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1280f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1281f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (sphere_mask) { 12835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_sphere_texgen(p, out_texgen, sphere_mask); 1284f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1285f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1286f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reflect_mask) { 12875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_reflect_texgen(p, out_texgen, reflect_mask); 1288f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1289f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1290f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (normal_mask) { 1291f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 12927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal ); 1293f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1294f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1295f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (copy_mask) { 1296f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); 12977e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); 1298f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1299f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1300f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1301f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) { 1302f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg texmat[4]; 13035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg in = (!is_undef(out_texgen) ? 13045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell out_texgen : 13055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_input(p, VERT_ATTRIB_TEX0+i)); 130610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 1307fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 1308fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul 0, texmat ); 130910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, out, texmat, in ); 131010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 131110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 1312fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 1313fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul STATE_MATRIX_TRANSPOSE, texmat ); 13141c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell emit_transpose_matrix_transform_vec4( p, out, texmat, in ); 131510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps(p); 131910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1320c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 132110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); 1322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1324f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_pointsize( struct tnl_program *p ) 1328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1329f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 13305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_size = register_param1(p, STATE_POINT_SIZE); 13315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); 13325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg out = register_output(p, VERT_RESULT_PSIZ); 1333f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ut = get_temp(p); 1334f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1335a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger /* dist = |eyez| */ 1336a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op1(p, OPCODE_ABS, ut, WRITEMASK_Y, swizzle1(eye, Z)); 133754dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* p1 + dist * (p2 + dist * p3); */ 1338a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), 133954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); 1340a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), 134154dac2c84310536cce962101de29546d3eb80175Roland Scheidegger ut, swizzle1(state_attenuation, X)); 134254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 134354dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* 1 / sqrt(factor) */ 1344a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); 134554dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 134654dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#if 1 134754dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* out = pointSize / sqrt(factor) */ 134854dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); 134954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#else 135054dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* not sure, might make sense to do clamping here, 135154dac2c84310536cce962101de29546d3eb80175Roland Scheidegger but it's not done in t_vb_points neither */ 1352a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); 1353a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); 135454dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); 135554dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#endif 1356f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1357f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ut); 1358f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1360a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void build_tnl_program( struct tnl_program *p ) 1361a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ /* Emit the program, starting with modelviewproject: 1362a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1363a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_hpos(p); 1364a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1365a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Lighting calculations: 1366a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1367c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & (FRAG_BIT_COL0|FRAG_BIT_COL1)) { 1368c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->light_global_enabled) 1369c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell build_lighting(p); 1370c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 1371c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) 1372c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); 1373c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1374c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) 1375f31448f3c86697275bffe5363d473dd128cbd2acAapo Tahkola emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1); 1376c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1377c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1378f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1379c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if ((p->state->fragprog_inputs_read & FRAG_BIT_FOGC) || 1380c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->state->fog_mode != FOG_NONE) 1381a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_fog(p); 13825a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1383c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BITS_TEX_ANY) 1384a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_texture_transform(p); 13855a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1386a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->point_attenuated) 1387a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_pointsize(p); 13885a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1389a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Finish up: 1390a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 13917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_END, undef, 0, undef); 13925a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1393a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Disassemble: 1394a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1395a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (DISASSEM) { 1396a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_printf ("\n"); 1397a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 13985a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell} 13995a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1400f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1401c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paulstatic void 1402c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paulcreate_new_program( const struct state_key *key, 1403122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_vertex_program *program, 1404c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paul GLuint max_temps) 1405f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1406f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct tnl_program p; 1407f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 140849d8cbe8d110e5c0a23300b5b82d110286bc3609Keith Whitwell _mesa_memset(&p, 0, sizeof(p)); 1409a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.state = key; 1410a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.program = program; 1411f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position = undef; 1412f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position_normalized = undef; 1413f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_normal = undef; 1414f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.identity = undef; 14153509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_in_use = 0; 1416a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1417a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (max_temps >= sizeof(int) * 8) 14183509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_reserved = 0; 14193509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell else 1420a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.temp_reserved = ~((1<<max_temps)-1); 14213509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell 1422002762b13aa58ca569a564bb64672e343611c9edBrian Paul p.program->Base.Instructions = _mesa_alloc_instructions(MAX_INSN); 1423002762b13aa58ca569a564bb64672e343611c9edBrian Paul p.program->Base.String = NULL; 1424f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumInstructions = 1425f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumTemporaries = 1426f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumParameters = 1427f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1428de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1429de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.InputsRead = 0; 1430de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.OutputsWritten = 0; 1431f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1432a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_tnl_program( &p ); 1433a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1434f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1435a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void *search_cache( struct tnl_cache *cache, 1436a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash, 1437a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const void *key, 1438a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint keysize) 1439a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 144037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c; 1441a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 144237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = cache->items[hash % cache->size]; c; c = c->next) { 1443aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0) 1444a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return c->data; 1445a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1446a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1447a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return NULL; 1448a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1449a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 145037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkolastatic void rehash( struct tnl_cache *cache ) 145137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola{ 145237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item **items; 145337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c, *next; 145437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola GLuint size, i; 145537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 145637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola size = cache->size * 3; 14579580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul items = (struct tnl_cache_item**) _mesa_malloc(size * sizeof(*items)); 145837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola _mesa_memset(items, 0, size * sizeof(*items)); 145937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 146037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (i = 0; i < cache->size; i++) 146137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = cache->items[i]; c; c = next) { 146237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola next = c->next; 146337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola c->next = items[c->hash % size]; 146437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola items[c->hash % size] = c; 146537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola } 146637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 146737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(cache->items); 146837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->items = items; 146937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->size = size; 147037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola} 147137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 147237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkolastatic void cache_item( struct tnl_cache *cache, 1473a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash, 1474a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell void *key, 1475a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell void *data ) 1476a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 14779580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul struct tnl_cache_item *c = (struct tnl_cache_item*) _mesa_malloc(sizeof(*c)); 1478a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->hash = hash; 1479a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->key = key; 1480a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->data = data; 148137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 148237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola if (++cache->n_items > cache->size * 1.5) 148337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola rehash(cache); 148437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 148537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola c->next = cache->items[hash % cache->size]; 148637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->items[hash % cache->size] = c; 1487a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1488a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1489a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint hash_key( struct state_key *key ) 1490a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1491a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint *ikey = (GLuint *)key; 1492a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash = 0, i; 1493a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1494a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* I'm sure this can be improved on, but speed is important: 1495f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1496a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < sizeof(*key)/sizeof(GLuint); i++) 1497a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell hash ^= ikey[i]; 1498f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1499a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return hash; 1500a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1501f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1502a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) 1503a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1504a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 1505a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct state_key *key; 1506a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash; 1507122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_vertex_program *prev = ctx->VertexProgram._Current; 1508f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1509dba21ed913da2222e3b55fc8ba724ca93acbabf1Nicolai Hähnle if (!ctx->VertexProgram._Current || 1510dba21ed913da2222e3b55fc8ba724ca93acbabf1Nicolai Hähnle ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) { 1511c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Grab all the relevent state and put it in a single structure: 1512c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 1513c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key = make_state_key(ctx); 1514c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell hash = hash_key(key); 1515c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1516c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Look for an already-prepared program for this state: 1517c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 1518a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *) 1519c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell search_cache( tnl->vp_cache, hash, key, sizeof(*key) ); 1520a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1521c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* OK, we'll have to build a new one: 1522c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 1523a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul if (!ctx->VertexProgram._TnlProgram) { 1524c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (0) 1525c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell _mesa_printf("Build new TNL program\n"); 1526c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1527a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *) 1528c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); 1529dbeea25bb834479a29712100888c862348112018Keith Whitwell 1530a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul create_new_program( key, ctx->VertexProgram._TnlProgram, 1531c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell ctx->Const.VertexProgram.MaxTemps ); 1532dbeea25bb834479a29712100888c862348112018Keith Whitwell 1533c9515bf1aec3a3d934535a9d2893e90e8b903043Keith Whitwell if (ctx->Driver.ProgramStringNotify) 1534c9515bf1aec3a3d934535a9d2893e90e8b903043Keith Whitwell ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB, 1535a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul &ctx->VertexProgram._TnlProgram->Base ); 1536a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1537a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram ); 1538c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1539c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 1540c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell FREE(key); 1541c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (0) 1542c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell _mesa_printf("Found existing TNL program for key %x\n", hash); 1543c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1544a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ctx->VertexProgram._Current = ctx->VertexProgram._TnlProgram; 1545a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1546a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1547c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Tell the driver about the change. Could define a new target for 1548c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell * this? 1549a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1550a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul if (ctx->VertexProgram._Current != prev && ctx->Driver.BindProgram) { 1551122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, 1552122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul (struct gl_program *) ctx->VertexProgram._Current); 1553a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul } 1554a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1555a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 15569248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkolavoid _tnl_ProgramCacheInit( GLcontext *ctx ) 15579248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola{ 15589248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola TNLcontext *tnl = TNL_CONTEXT(ctx); 15599248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola 15609248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache = (struct tnl_cache *) MALLOC(sizeof(*tnl->vp_cache)); 15619248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->size = 17; 15629248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->n_items = 0; 15639248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->items = (struct tnl_cache_item**) 15649248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola _mesa_calloc(tnl->vp_cache->size * sizeof(*tnl->vp_cache->items)); 15659248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola} 1566a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1567a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_ProgramCacheDestroy( GLcontext *ctx ) 1568a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1569a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 157037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c, *next; 157137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola GLuint i; 1572a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 157337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (i = 0; i < tnl->vp_cache->size; i++) 157437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = tnl->vp_cache->items[i]; c; c = next) { 157537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola next = c->next; 157637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c->key); 157737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c->data); 157837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c); 157937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola } 158037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 158137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(tnl->vp_cache->items); 158237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(tnl->vp_cache); 1583f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1584