t_vp_build.c revision a8534885efb13ec7f071192c1504513cd90d07de
1f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* 2f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Mesa 3-D graphics library 3f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Version: 6.3 4f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 5f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Copyright (C) 2005 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" 36f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_context.h" 37f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_vp_build.h" 38f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 39f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/program.h" 40f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/nvvertprog.h" 41f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/arbvertparse.h" 42f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 43a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstruct state_key { 44a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_global_enabled:1; 45a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_local_viewer:1; 46a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_twoside:1; 47a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_color_material:1; 48a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_color_material_mask:12; 49a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_material_mask:12; 50a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 51a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned normalize:1; 52a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned rescale_normals:1; 53a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned fog_source_is_depth:1; 54a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned tnl_do_vertex_fog:1; 55a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned separate_specular:1; 56a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned fog_enabled:1; 57a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned fog_mode:2; 58a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned point_attenuated:1; 59a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned nr_tex:4; 60a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_enabled_global:1; 61a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 62a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct { 63a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_enabled:1; 64a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_eyepos3_is_zero:1; 65a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_spotcutoff_is_180:1; 66a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_attenuated:1; 67a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texunit_really_enabled:1; 68a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texmat_enabled:1; 69a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_enabled:4; 70a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode0:4; 71a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode1:4; 72a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode2:4; 73a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode3:4; 74a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } unit[8]; 75a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell}; 76a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 77a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 78a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 79a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define FOG_LINEAR 0 80a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define FOG_EXP 1 81a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define FOG_EXP2 2 82a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define FOG_UNKNOWN 3 83a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 84a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 85a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 86a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (mode) { 87a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 88a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EXP: return FOG_EXP; 89a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EXP2: return FOG_EXP2; 90a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell default: return FOG_UNKNOWN; 91a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 92a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 93a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 94a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_NONE 0 95a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_OBJ_LINEAR 1 96a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_EYE_LINEAR 2 97a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_SPHERE_MAP 3 98a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_REFLECTION_MAP 4 99a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_NORMAL_MAP 5 100a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 101a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint translate_texgen( GLboolean enabled, GLenum mode ) 102a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 103a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!enabled) 104a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return TXG_NONE; 105a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 106a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (mode) { 107a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_OBJECT_LINEAR: return TXG_OBJ_LINEAR; 108a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EYE_LINEAR: return TXG_EYE_LINEAR; 109a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_SPHERE_MAP: return TXG_SPHERE_MAP; 110a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_REFLECTION_MAP_NV: return TXG_REFLECTION_MAP; 111a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_NORMAL_MAP_NV: return TXG_NORMAL_MAP; 112a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell default: return TXG_NONE; 113a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 114a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 115a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 116a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic struct state_key *make_state_key( GLcontext *ctx ) 117a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 118a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 119a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct vertex_buffer *VB = &tnl->vb; 120a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct state_key *key = CALLOC_STRUCT(state_key); 121a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint i; 122a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 123a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->separate_specular = (ctx->Light.Model.ColorControl == 124a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GL_SEPARATE_SPECULAR_COLOR); 125a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 126a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Enabled) { 127a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_global_enabled = 1; 128a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 129a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Model.LocalViewer) 130a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_local_viewer = 1; 131a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 132a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Model.TwoSide) 133a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_twoside = 1; 134a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 135a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.ColorMaterialEnabled) 136a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_color_material = 1; 137a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 138a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.ColorMaterialBitmask) 139a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_color_material_mask = 1; 140a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 141a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT ; i < _TNL_ATTRIB_INDEX ; i++) 142a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (VB->AttribPtr[i]->stride) 143a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_material_mask |= 1<<i; 144a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 145a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 146a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct gl_light *light = &ctx->Light.Light[i]; 147a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 148a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->Enabled) { 149a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_enabled = 1; 150a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 151a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->EyePosition[3] == 0.0) 152a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_eyepos3_is_zero = 1; 153a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 154a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->SpotCutoff == 180.0) 155a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_spotcutoff_is_180 = 1; 156a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 157a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->ConstantAttenuation != 1.0 || 158a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell light->LinearAttenuation != 1.0 || 159a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell light->QuadraticAttenuation != 1.0) 160a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_attenuated = 1; 161a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 162a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 163a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 164a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 165a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Transform.Normalize) 166a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->normalize = 1; 167f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 168a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Transform.RescaleNormals) 169a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->rescale_normals = 1; 170a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 171a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Fog.Enabled) 172a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->fog_enabled = 1; 173a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 174a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (key->fog_enabled) { 175a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) 176a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->fog_source_is_depth = 1; 177a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 178a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (tnl->_DoVertexFog) 179a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->tnl_do_vertex_fog = 1; 180a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 181a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->fog_mode = translate_fog_mode(ctx->Fog.Mode); 182a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 183a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 184a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Point._Attenuated) 185a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->point_attenuated = 1; 186a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 187a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Texture._TexGenEnabled) 188a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->texgen_enabled_global = 1; 189a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 190a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 191a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 192a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 193a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (texUnit->_ReallyEnabled) 194a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texunit_really_enabled = 1; 195a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 196a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) 197a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texmat_enabled = 1; 198a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 199a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (texUnit->TexGenEnabled) { 200a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_enabled = 1; 201a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 202a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode0 = 203a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<0), 204a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeS ); 205a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode1 = 206a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<1), 207a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeT ); 208a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode2 = 209a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<2), 210a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeR ); 211a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode3 = 212a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<3), 213a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeQ ); 214a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 215a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 216a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 217a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return key; 218a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 219a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 220a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 221a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 222f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Very useful debugging tool - produces annotated listing of 223f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * generated program with line/function references for each 224f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * instruction back into this file: 225f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 2265f430c9976c71d7167f9327623e1df5fce53a970Keith Whitwell#define DISASSEM 0 22710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 22810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell/* Should be tunable by the driver - do we want to do matrix 22910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell * multiplications with DP4's or with MUL/MAD's? SSE works better 23010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell * with the latter, drivers may differ. 23110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 232a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define PREFER_DP4 0 233f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 2342fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell#define MAX_INSN 200 2352fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell 236f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Use uregs to represent registers internally, translate to Mesa's 237f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * expected formats on emit. 238f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 239f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * NOTE: These are passed by value extensively in this file rather 240f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * than as usual by pointer reference. If this disturbs you, try 241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * remembering they are just 32bits in size. 242f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * GCC is smart enough to deal with these dword-sized structures in 244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * much the same way as if I had defined them as dwords and was using 245f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * macros to access and set the fields. This is much nicer and easier 246f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * to evolve. 247f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 248f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct ureg { 249f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint file:4; 250f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint idx:8; 251f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint negate:1; 252f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint swz:12; 253f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint pad:7; 254f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 256f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct tnl_program { 258a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const struct state_key *state; 259f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct vertex_program *program; 260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 2613509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell GLuint temp_in_use; 262f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint temp_reserved; 263f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position; 265f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position_normalized; 266f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_normal; 267f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg identity; 268f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 269f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint materials; 270f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint color_materials; 271f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 272f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 273f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 274f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellconst static struct ureg undef = { 275f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell ~0, 276f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell ~0, 277f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 278f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 279f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0 280f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 281f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Local shorthand: 283f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 284f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define X SWIZZLE_X 285f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Y SWIZZLE_Y 286f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Z SWIZZLE_Z 287f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define W SWIZZLE_W 288f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 289f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 290f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Construct a ureg: 291f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 292f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx) 293f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 294f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg; 295f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.file = file; 296f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.idx = idx; 297f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate = 0; 298f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = SWIZZLE_NOOP; 299f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.pad = 0; 300f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 301f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 302f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 303f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 304f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 305f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg negate( struct ureg reg ) 306f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 307f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate ^= 1; 308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 309f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 310f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 311f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 314f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 315f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, y), 316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, z), 317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, w)); 318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 319f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 324f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return swizzle(reg, x, x, x, x); 325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_temp( struct tnl_program *p ) 328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 3293509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell int bit = ffs( ~p->temp_in_use ); 330f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!bit) { 331f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell fprintf(stderr, "%s: out of temporaries\n", __FILE__); 332f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell exit(1); 333f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 334f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 3353509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use |= 1<<(bit-1); 336f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_TEMPORARY, bit-1); 337f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 338f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 339f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg reserve_temp( struct tnl_program *p ) 340f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 341f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp( p ); 342f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_reserved |= 1<<temp.idx; 343f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 344f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 345f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 346f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temp( struct tnl_program *p, struct ureg reg ) 347f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 348f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY) { 3493509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use &= ~(1<<reg.idx); 3503509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use |= p->temp_reserved; /* can't release reserved temps */ 351f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 352f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 353f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 354f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temps( struct tnl_program *p ) 355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 3563509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use = p->temp_reserved; 357f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 358f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_input( struct tnl_program *p, GLuint input ) 362f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 363f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->program->InputsRead |= (1<<input); 364f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_INPUT, input); 365f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 366f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 367f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_output( struct tnl_program *p, GLuint output ) 368f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 369f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->program->OutputsWritten |= (1<<output); 370f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_OUTPUT, output); 371f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 372f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 373f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_const4f( struct tnl_program *p, 374f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s0, 375f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s1, 376f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s2, 377f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s3) 378f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 379f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat values[4]; 380f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint idx; 381f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[0] = s0; 382f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[1] = s1; 383f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[2] = s2; 384f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[3] = s3; 385f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell idx = _mesa_add_unnamed_constant( p->program->Parameters, values ); 386f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 387f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 388f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 389f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 39096582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 391f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 392f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 393f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 394f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLboolean is_undef( struct ureg reg ) 395f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 396f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg.file == 0xf; 397f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 398f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 399f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_identity_param( struct tnl_program *p ) 400f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 401f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->identity)) 402f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->identity = register_const4f(p, 0,0,0,1); 403f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 404f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->identity; 405f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 406f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 407f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_param6( struct tnl_program *p, 408f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s0, 409f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s1, 410f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s2, 411f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s3, 412f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s4, 413f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s5) 414f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 415f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint tokens[6]; 416f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint idx; 417f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[0] = s0; 418f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[1] = s1; 419f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[2] = s2; 420f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[3] = s3; 421f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[4] = s4; 422f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[5] = s5; 423f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell idx = _mesa_add_state_reference( p->program->Parameters, tokens ); 424f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 425f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 426f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 427f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 428f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0) 429f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0) 430f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0) 431f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0) 432f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 433f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 434f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void register_matrix_param6( struct tnl_program *p, 435f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s0, 436f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s1, 437f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s2, 438f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s3, 439f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s4, 440f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s5, 441f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg *matrix ) 442f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 443f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i; 444f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 445f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* This is a bit sad as the support is there to pull the whole 446f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * matrix out in one go: 447f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 448f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i <= s4 - s3; i++) 449f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 ); 450f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 451f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 452f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 453f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_arg( struct vp_src_register *src, 454f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg ) 455f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 456f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->File = reg.file; 457f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Index = reg.idx; 458f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Swizzle = reg.swz; 459f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Negate = reg.negate; 460f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->RelAddr = 0; 461f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->pad = 0; 462f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 463f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 464f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_dst( struct vp_dst_register *dst, 465f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg, GLuint mask ) 466f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 467f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->File = reg.file; 468f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->Index = reg.idx; 4695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* allow zero as a shorthand for xyzw */ 4705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell dst->WriteMask = mask ? mask : WRITEMASK_XYZW; 471f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->pad = 0; 472f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 473f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 4745f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void debug_insn( struct vp_instruction *inst, const char *fn, 4755f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint line ) 476f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 477f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#if DISASSEM 478f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell static const char *last_fn; 479f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 480f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (fn != last_fn) { 481f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell last_fn = fn; 482f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_printf("%s:\n", fn); 483f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 484f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 485f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_printf("%d:\t", line); 486f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_debug_vp_inst(1, inst); 487f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#endif 488f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 489f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 490f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 491f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_op3fn(struct tnl_program *p, 492f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint op, 493f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 494f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint mask, 495f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src0, 496f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src1, 497f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src2, 498f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const char *fn, 499f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint line) 500f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 501f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr = p->program->Base.NumInstructions++; 502f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct vp_instruction *inst = &p->program->Instructions[nr]; 503f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5042fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell if (p->program->Base.NumInstructions > MAX_INSN) { 505a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_problem(0, "Out of instructions in emit_op3fn\n"); 5062fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell return; 5072fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell } 5082fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell 509f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell inst->Opcode = op; 510dbeea25bb834479a29712100888c862348112018Keith Whitwell inst->StringPos = 0; 511dbeea25bb834479a29712100888c862348112018Keith Whitwell inst->Data = 0; 512f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 513f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 514f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 515f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 516f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 517f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_dst( &inst->DstReg, dest, mask ); 518f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 519f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell debug_insn(inst, fn, line); 520f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 521f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 522f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 523f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5245f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op3(p, op, dst, mask, src0, src1, src2) \ 5255f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__) 5265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5275f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op2(p, op, dst, mask, src0, src1) \ 5285f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__) 5295f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op1(p, op, dst, mask, src0) \ 5315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__) 532f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 533f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 534f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_temp( struct tnl_program *p, struct ureg reg ) 535f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 536f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY && 537f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell !(p->temp_reserved & (1<<reg.idx))) 538f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 539f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 540f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp(p); 541f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, temp, 0, reg); 542f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 543f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 544f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 545f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 546f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 547f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Currently no tracking performed of input/output/register size or 548f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * active elements. Could be used to reduce these operations, as 549f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * could the matrix type. 550f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 551f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec4( struct tnl_program *p, 552f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 553f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 554f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 555f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 556f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]); 557f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]); 558f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]); 559f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]); 5605f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 5615f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 56247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell/* This version is much easier to implement if writemasks are not 56347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * supported natively on the target or (like SSE), the target doesn't 56447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * have a clean/obvious dotproduct implementation. 56547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 5665f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void emit_transpose_matrix_transform_vec4( struct tnl_program *p, 5675f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 5685f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell const struct ureg *mat, 5695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg src) 5705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 5715f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp; 5725f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5735f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell if (dest.file != PROGRAM_TEMPORARY) 5745f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell tmp = get_temp(p); 5755f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell else 5765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell tmp = dest; 577f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); 5795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3(p, VP_OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); 5805f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3(p, VP_OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); 5815f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3(p, VP_OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); 5825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell if (dest.file != PROGRAM_TEMPORARY) 5845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, tmp); 585f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 586f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 587f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec3( struct tnl_program *p, 588f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 589f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 590f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 591f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 592f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]); 593f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]); 594f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]); 595f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 596f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 597f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 598f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_normalize_vec3( struct tnl_program *p, 599f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 600f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src ) 601f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 602f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 603f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, src, src); 604f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RSQ, tmp, 0, tmp); 605f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, dest, 0, src, tmp); 606f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 607f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 608f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 60910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwellstatic void emit_passthrough( struct tnl_program *p, 61010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell GLuint input, 61110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell GLuint output ) 61210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell{ 61310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg out = register_output(p, output); 61410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_op1(p, VP_OPCODE_MOV, out, 0, register_input(p, input)); 61510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell} 61610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 617f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position( struct tnl_program *p ) 618f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 619f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position)) { 620f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 621f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg modelview[4]; 622f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 623f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position = reserve_temp(p); 624f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 62510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 62610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, 62710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX, modelview ); 62810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 62910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); 63010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 63110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 63210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, 63310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX_TRANSPOSE, modelview ); 63410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 63510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); 63610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 637f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 638f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 639f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position; 640f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 641f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 642f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 643f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position_normalized( struct tnl_program *p ) 644f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 645f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position_normalized)) { 646f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 647f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position_normalized = reserve_temp(p); 648f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, p->eye_position_normalized, eye); 649f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 650f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 651f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position_normalized; 652f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 653f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 654f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 655f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_normal( struct tnl_program *p ) 656f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 657f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_normal)) { 658f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); 659f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvinv[3]; 660f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 6615f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, 6625f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_MATRIX_INVTRANS, mvinv ); 663f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 664f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_normal = reserve_temp(p); 665f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 666f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Transform to eye space: 667f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 668f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal ); 669f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 670f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Normalize/Rescale: 671f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 672a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->normalize) { 673f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3( p, p->eye_normal, p->eye_normal ); 674f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 675a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell else if (p->state->rescale_normals) { 6765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg rescale = register_param2(p, STATE_INTERNAL, 6775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_NORMAL_SCALE); 6785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 6795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2( p, VP_OPCODE_MUL, p->eye_normal, 0, normal, 6805f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell swizzle1(rescale, X)); 681f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 682f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 683f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 684f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_normal; 685f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 686f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 687f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 688f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 689f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_hpos( struct tnl_program *p ) 690f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 691f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 692f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); 693f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvp[4]; 694f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 69510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 69610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, 69710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX, mvp ); 69810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, hpos, mvp, pos ); 69910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 70010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 70110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, 70210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX_TRANSPOSE, mvp ); 70310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); 70410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 705f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 706f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 707f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 708f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLuint material_attrib( GLuint side, GLuint property ) 709f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 7105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell return (_TNL_ATTRIB_MAT_FRONT_AMBIENT + 7115f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell (property - STATE_AMBIENT) * 2 + 7125f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell side); 713f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 714f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 715f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void set_material_flags( struct tnl_program *p ) 716f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 717f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->color_materials = 0; 718f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 0; 719f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 720a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_color_material) { 721f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 722a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->color_materials = p->state->light_color_material_mask; 723f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 724f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 725a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->materials |= p->state->light_material_mask; 726f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 727f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 728f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 7295f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_material( struct tnl_program *p, GLuint side, 7305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint property ) 731f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 732f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 733f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 734f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->color_materials & (1<<attrib)) 735f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_input(p, VERT_ATTRIB_COLOR0); 736f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else if (p->materials & (1<<attrib)) 737f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_input( p, attrib ); 738f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 739f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param3( p, STATE_MATERIAL, side, property ); 740f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 741f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 742f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define SCENE_COLOR_BITS(side) (( _TNL_BIT_MAT_FRONT_EMISSION | \ 743f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _TNL_BIT_MAT_FRONT_AMBIENT | \ 744f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _TNL_BIT_MAT_FRONT_DIFFUSE) << (side)) 745f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 746f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Either return a precalculated constant value or emit code to 747f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * calculate these values dynamically in the case where material calls 748f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * are present between begin/end pairs. 749f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 750f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Probably want to shift this to the program compilation phase - if 751f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * we always emitted the calculation here, a smart compiler could 752f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * detect that it was constant (given a certain set of inputs), and 753f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * lift it out of the main loop. That way the programs created here 754f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * would be independent of the vertex_buffer details. 755f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 756f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) 757f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 758f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & SCENE_COLOR_BITS(side)) { 7595f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); 760f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_emission = get_material(p, side, STATE_EMISSION); 761f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); 762f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); 763f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = make_temp(p, material_diffuse); 7645f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3(p, VP_OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, 7655f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell material_ambient, material_emission); 766f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 767f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 768f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 769f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side ); 770f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 771f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 772f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 7735f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_lightprod( struct tnl_program *p, GLuint light, 7745f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint side, GLuint property ) 775f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 776f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 777f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & (1<<attrib)) { 7785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg light_value = 7795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_param3(p, STATE_LIGHT, light, property); 780f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_value = get_material(p, side, property); 781f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 782f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, light_value, material_value); 783f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 784f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 785f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 786f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param4(p, STATE_LIGHTPROD, light, side, property); 787f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 788f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 7895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg calculate_light_attenuation( struct tnl_program *p, 7905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint i, 7915f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg VPpli, 7925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dist ) 7935f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 7945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg attenuation = register_param3(p, STATE_LIGHT, i, 7955f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_ATTENUATION); 7965f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg att = get_temp(p); 7975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 7985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Calculate spot attenuation: 7995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 800a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180) { 8015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg spot_dir = register_param3(p, STATE_LIGHT, i, 8025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_SPOT_DIRECTION); 8035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg spot = get_temp(p); 8045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg slt = get_temp(p); 8055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_normalize_vec3( p, spot, spot_dir ); /* XXX: precompute! */ 8075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_DP3, spot, 0, negate(VPpli), spot_dir); 8085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_SLT, slt, 0, swizzle1(spot_dir,W), spot); 8095f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); 8105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_MUL, att, 0, slt, spot); 8115f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8125f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, spot); 8135f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, slt); 8145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8165f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Calculate distance attenuation: 8175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 818a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_attenuated) { 8195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/d,d,d,1/d */ 8215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op1(p, VP_OPCODE_RCP, dist, WRITEMASK_YZ, dist); 8225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1,d,d*d,1/d */ 8235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_MUL, dist, WRITEMASK_XZ, dist, swizzle1(dist,Y)); 8245f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/dist-atten */ 8255f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dist, 0, attenuation, dist); 8265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 827a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180) { 8285f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* dist-atten */ 8295f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op1(p, VP_OPCODE_RCP, dist, 0, dist); 8305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* spot-atten * dist-atten */ 8315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_MUL, att, 0, dist, att); 8325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } else { 8335f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* dist-atten */ 8345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op1(p, VP_OPCODE_RCP, att, 0, dist); 8355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell return att; 8395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 8405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8415f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 842f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 843f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 844f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 845f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Need to add some addtional parameters to allow lighting in object 846f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye 847f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space lighting. 848f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 849f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_lighting( struct tnl_program *p ) 850f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 851a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const GLboolean twoside = p->state->light_twoside; 852a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const GLboolean separate = p->state->separate_specular; 853f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr_lights = 0, count = 0; 854f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 855f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg lit = get_temp(p); 856f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dots = get_temp(p); 857f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _col0 = undef, _col1 = undef; 858f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _bfc0 = undef, _bfc1 = undef; 859f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i; 860f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 861f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) 862a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_enabled) 863f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell nr_lights++; 864f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 865f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell set_material_flags(p); 866f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 867f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 868f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 0, STATE_SHININESS); 869f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); 870f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 871f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 872f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col0 = make_temp(p, get_scenecolor(p, 0)); 873f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 874f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = make_temp(p, get_identity_param(p)); 875f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 876f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = _col0; 877f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 878f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 879f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 880f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 881f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 1, STATE_SHININESS); 8825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op1(p, VP_OPCODE_MOV, dots, WRITEMASK_Z, 8835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell negate(swizzle1(shininess,X))); 884f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 885f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 886f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc0 = make_temp(p, get_scenecolor(p, 1)); 887f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 888f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = make_temp(p, get_identity_param(p)); 889f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 890f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = _bfc0; 891f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 892f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 89310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 89410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell /* If no lights, still need to emit the scenecolor. 89510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 89610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (nr_lights == 0) { 89710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell { 89810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); 89910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_op1(p, VP_OPCODE_MOV, res0, 0, _col0); 90010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 90110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 90210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (separate) { 90310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); 90410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_op1(p, VP_OPCODE_MOV, res1, 0, _col1); 90510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 90610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 90710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside) { 90810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); 90910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_op1(p, VP_OPCODE_MOV, res0, 0, _bfc0); 91010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 91110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 91210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside && separate) { 91310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); 91410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_op1(p, VP_OPCODE_MOV, res1, 0, _bfc1); 91510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 91610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 91710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell release_temps(p); 91810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell return; 91910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 92010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 92110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 922f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 923a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_enabled) { 924f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg half = undef; 925f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg att = undef, VPpli = undef; 926f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 927f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell count++; 928f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 929a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_eyepos3_is_zero) { 93047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Can used precomputed constants in this case. 93147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * Attenuation never applies to infinite lights. 932f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9335f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell VPpli = register_param3(p, STATE_LIGHT, i, 9345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION_NORMALIZED); 935f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell half = register_param3(p, STATE_LIGHT, i, STATE_HALF); 936f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 937f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 9385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg Ppli = register_param3(p, STATE_LIGHT, i, 9395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION); 940f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg V = get_eye_position(p); 9415f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dist = get_temp(p); 942f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 943f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell VPpli = get_temp(p); 944f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell half = get_temp(p); 945f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 946f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calulate VPpli vector 947f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 948f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_SUB, VPpli, 0, Ppli, V); 949f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 9505f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Normalize VPpli. The dist value also used in 951f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * attenuation below. 952f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9535f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dist, 0, VPpli, VPpli); 9545f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op1(p, VP_OPCODE_RSQ, dist, 0, dist); 9555f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_MUL, VPpli, 0, VPpli, dist); 956f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 957f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 958f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate attenuation: 959f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 960a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180 || 961a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->state->unit[i].light_attenuated) { 962a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell att = calculate_light_attenuation(p, i, VPpli, dist); 963f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 964f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 965f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 966f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate viewer direction, or use infinite viewer: 967f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 968a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_local_viewer) { 969f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 970f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_SUB, half, 0, VPpli, eye_hat); 971f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 972f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 9735f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); 974f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_ADD, half, 0, VPpli, z_dir); 975f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 976f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 977f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, half, half); 978f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 9795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, dist); 980f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 981f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 982f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate dot products: 983f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 984f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); 985f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dots, WRITEMASK_Y, normal, half); 986f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 987f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 988f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Front face lighting: 989f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 990f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 991f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); 992f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); 993f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); 994f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 995f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 996f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_LIT, lit, 0, dots); 997f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 998f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 999f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, lit, 0, lit, att); 1000f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 100147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1002f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1003f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1004f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_COL0 ); 1005f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL1 ); 1006f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1007f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1008f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1009f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL0 ); 1010f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1011f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1012f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1013f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _col1; 1014f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1015f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1016f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); 1017f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res0, 0, swizzle1(lit,Y), diffuse, _col0); 1018f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res1, 0, swizzle1(lit,Z), specular, _col1); 1019f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1020f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1021f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1022f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1023f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1024f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1025f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Back face lighting: 1026f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1027f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 1028f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); 1029f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); 1030f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); 1031f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 1032f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1033f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_LIT, lit, 0, negate(swizzle(dots,X,Y,W,Z))); 1034f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1035f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 1036f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, lit, 0, lit, att); 1037f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1038f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1039f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1040f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_BFC0 ); 1041f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC1 ); 1042f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1043f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1044f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1045f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC0 ); 1046f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1047f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1048f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1049f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _bfc1; 1050f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1051f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1052f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1053f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); 1054f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res0, 0, swizzle1(lit,Y), diffuse, _bfc0); 1055f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res1, 0, swizzle1(lit,Z), specular, _bfc1); 1056f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1057f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1058f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1059f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1060f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1061f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1062f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, half); 1063f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, VPpli); 1064f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, att); 1065f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1066f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1067f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1068f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps( p ); 1069f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1070f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1071f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1072f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_fog( struct tnl_program *p ) 1073f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1074f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg fog = register_output(p, VERT_RESULT_FOGC); 1075f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg input; 10765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 1077a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->fog_source_is_depth) { 1078f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(get_eye_position(p), Z); 1079f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1080f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1081f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); 1082f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1083f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1084a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->tnl_do_vertex_fog) { 1085f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg params = register_param1(p, STATE_FOG_PARAMS); 1086f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 1087f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1088a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (p->state->fog_mode) { 1089a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_LINEAR: { 1090f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg id = get_identity_param(p); 1091f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_SUB, tmp, 0, swizzle1(params,Z), input); 1092f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, swizzle1(params,W)); 1093f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ 10945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); 1095f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1096f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1097a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP: 1098f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_ABS, tmp, 0, input); 1099f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, swizzle1(params,X)); 11005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_POW, fog, WRITEMASK_X, 11015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_const1f(p, M_E), negate(tmp)); 1102f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1103a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP2: 1104f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, input, swizzle1(params,X)); 1105f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, tmp); 11065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_POW, fog, WRITEMASK_X, 11075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_const1f(p, M_E), negate(tmp)); 1108f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1109f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1110f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1111f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 1112f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1113f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1114f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* results = incoming fog coords (compute fog per-fragment later) 1115f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 1116f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * KW: Is it really necessary to do anything in this case? 1117f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1118f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, fog, WRITEMASK_X, input); 1119f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1120f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 11215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_reflect_texgen( struct tnl_program *p, 11235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 11245f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 11255f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 11265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 11275f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 11285f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 1129f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 11305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 11315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, normal, eye_hat); 11325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 11335f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_ADD, tmp, 0, tmp, tmp); 11345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 11355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3(p, VP_OPCODE_MAD, dest, writemask, negate(tmp), normal, eye_hat); 11365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 11375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_sphere_texgen( struct tnl_program *p, 11395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 11405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 11415f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 11425f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 11435f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 11445f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 114596582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell struct ureg half = register_scalar_const(p, .5); 11465f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg r = get_temp(p); 11475f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg inv_m = get_temp(p); 11485f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg id = get_identity_param(p); 11495f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11505f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Could share the above calculations, but it would be 11515f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * a fairly odd state for someone to set (both sphere and 11525f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflection active for different texture coordinate 11535f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * components. Of course - if two texture units enable 11545f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflect and/or sphere, things start to tilt in favour 11555f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * of seperating this out: 11565f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 11575f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11585f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 11595f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, normal, eye_hat); 11605f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 11615f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_ADD, tmp, 0, tmp, tmp); 11625f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 11635f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3(p, VP_OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat); 11645f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r + 0,0,1 */ 11655f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_ADD, tmp, 0, r, swizzle(id,X,Y,W,Z)); 11665f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* rx^2 + ry^2 + (rz+1)^2 */ 11675f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, tmp, tmp); 11685f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2/m */ 11695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op1(p, VP_OPCODE_RSQ, tmp, 0, tmp); 11705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/m */ 117196582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell emit_op2(p, VP_OPCODE_MUL, inv_m, 0, tmp, half); 11725f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r/m + 1/2 */ 117396582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell emit_op3(p, VP_OPCODE_MAD, dest, writemask, r, inv_m, half); 11745f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11755f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, tmp); 11765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, r); 11775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, inv_m); 11785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 1179f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1180f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1181f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_texture_transform( struct tnl_program *p ) 1182f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1183f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i, j; 1184f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1185a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 1186a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint texmat_enabled = p->state->unit[i].texmat_enabled; 1187f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1188a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].texgen_enabled || texmat_enabled) { 118910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); 1190f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg out_texgen = undef; 1191f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1192a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].texgen_enabled) { 1193f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint copy_mask = 0; 1194f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint sphere_mask = 0; 1195f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint reflect_mask = 0; 1196f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint normal_mask = 0; 1197f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint modes[4]; 1198f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1199f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) 1200f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = get_temp(p); 1201f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 1202f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = out; 1203f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1204a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[0] = p->state->unit[i].texgen_mode0; 1205a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[1] = p->state->unit[i].texgen_mode1; 1206a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[2] = p->state->unit[i].texgen_mode2; 1207a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[3] = p->state->unit[i].texgen_mode3; 1208f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1209f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (j = 0; j < 4; j++) { 1210a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (modes[j]) { 1211a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_OBJ_LINEAR: { 1212a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg obj = register_input(p, VERT_ATTRIB_POS); 1213a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1214a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1215a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_OBJECT_S + j); 1216a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1217a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell emit_op2(p, VP_OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1218a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell obj, plane ); 1219a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1220f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1221a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_EYE_LINEAR: { 1222a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg eye = get_eye_position(p); 1223a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1224a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1225a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_EYE_S + j); 1226a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1227a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell emit_op2(p, VP_OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1228a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell eye, plane ); 1229a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1230a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1231a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_SPHERE_MAP: 1232a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell sphere_mask |= WRITEMASK_X << j; 1233a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1234a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_REFLECTION_MAP: 1235a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell reflect_mask |= WRITEMASK_X << j; 1236a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1237a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NORMAL_MAP: 1238a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell normal_mask |= WRITEMASK_X << j; 1239a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1240a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NONE: 1241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell copy_mask |= WRITEMASK_X << j; 1242a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1243a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1245f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1246f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1247f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (sphere_mask) { 12485f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_sphere_texgen(p, out_texgen, sphere_mask); 1249f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1250f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1251f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reflect_mask) { 12525f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_reflect_texgen(p, out_texgen, reflect_mask); 1253f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1254f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (normal_mask) { 1256f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 1257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, out_texgen, normal_mask, normal ); 1258f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1259f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (copy_mask) { 1261f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); 1262f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, out_texgen, copy_mask, in ); 1263f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1265f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1266f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) { 1267f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg texmat[4]; 12685f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg in = (!is_undef(out_texgen) ? 12695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell out_texgen : 12705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_input(p, VERT_ATTRIB_TEX0+i)); 127110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 127210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 127310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 0, 3, STATE_MATRIX, texmat ); 127410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, out, texmat, in ); 127510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 127610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 127710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 127810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 0, 3, STATE_MATRIX_TRANSPOSE, texmat ); 127910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, out, texmat, in ); 128010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1281f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1283f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps(p); 128410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1285a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell else if (p->state->unit[i].texunit_really_enabled) { 128610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell /* KW: _ReallyEnabled isn't sufficient? Need to know whether 128710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell * this texture unit is referenced by the fragment shader. 128810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 128910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); 1290f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1291f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1292f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1293f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1294f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1295f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Seems like it could be tighter: 1296f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1297f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_pointsize( struct tnl_program *p ) 1298f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1299f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 13005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_size = register_param1(p, STATE_POINT_SIZE); 13015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); 13025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg out = register_output(p, VERT_RESULT_PSIZ); 1303f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ut = get_temp(p); 1304f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1305f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* 1, -Z, Z * Z, 1 */ 1306f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, ut, 0, swizzle1(get_identity_param(p), W)); 1307f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, ut, WRITEMASK_YZ, ut, negate(swizzle1(eye, Z))); 1308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, ut, WRITEMASK_Z, ut, negate(swizzle1(eye, Z))); 1309f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1310f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 13115f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* p1 + p2 * dist + p3 * dist * dist, 0 */ 1312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, ut, 0, ut, state_attenuation); 1313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1314f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* 1 / factor */ 1315f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RCP, ut, 0, ut ); 1316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* out = pointSize / factor */ 1318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, out, WRITEMASK_X, ut, state_size); 1319f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ut); 1321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1323a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void build_tnl_program( struct tnl_program *p ) 1324a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ /* Emit the program, starting with modelviewproject: 1325a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1326a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_hpos(p); 1327a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1328a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Lighting calculations: 1329a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1330a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_global_enabled) 1331a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_lighting(p); 1332a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell else 1333a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); 1334f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1335a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->fog_enabled) 1336a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_fog(p); 13375a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1338a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->nr_tex) 1339a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_texture_transform(p); 13405a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1341a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->point_attenuated) 1342a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_pointsize(p); 13435a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1344a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Finish up: 1345a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1346a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell emit_op1(p, VP_OPCODE_END, undef, 0, undef); 13475a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1348a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Disassemble: 1349a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1350a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (DISASSEM) { 1351a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_printf ("\n"); 1352a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 13535a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell} 13545a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1356a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid create_new_program( const struct state_key *key, 1357a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct vertex_program *program, 1358a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint max_temps) 1359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct tnl_program p; 1361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 136249d8cbe8d110e5c0a23300b5b82d110286bc3609Keith Whitwell _mesa_memset(&p, 0, sizeof(p)); 1363a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.state = key; 1364a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.program = program; 1365f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position = undef; 1366f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position_normalized = undef; 1367f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_normal = undef; 1368f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.identity = undef; 13693509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_in_use = 0; 1370a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1371a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (max_temps >= sizeof(int) * 8) 13723509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_reserved = 0; 13733509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell else 1374a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.temp_reserved = ~((1<<max_temps)-1); 13753509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell 13762fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell p.program->Instructions = MALLOC(sizeof(struct vp_instruction) * MAX_INSN); 1377f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.String = 0; 1378f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumInstructions = 1379f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumTemporaries = 1380f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumParameters = 1381f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1382a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.program->Parameters = _mesa_new_parameter_list(); 1383f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->InputsRead = 0; 1384f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->OutputsWritten = 0; 1385f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1386a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_tnl_program( &p ); 1387a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1388f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1389a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void *search_cache( struct tnl_cache *cache, 1390a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash, 1391a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const void *key, 1392a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint keysize) 1393a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1394a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct tnl_cache *c; 1395a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1396a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (c = cache; c; c = c->next) { 1397a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (c->hash == hash && memcmp(c->key, key, keysize) == 0) 1398a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return c->data; 1399a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1400a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1401a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return NULL; 1402a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1403a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1404a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void cache_item( struct tnl_cache **cache, 1405a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash, 1406a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell void *key, 1407a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell void *data ) 1408a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1409a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct tnl_cache *c = MALLOC(sizeof(*c)); 1410a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->hash = hash; 1411a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->key = key; 1412a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->data = data; 1413a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->next = *cache; 1414a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell *cache = c; 1415a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1416a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1417a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint hash_key( struct state_key *key ) 1418a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1419a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint *ikey = (GLuint *)key; 1420a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash = 0, i; 1421a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1422a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* I'm sure this can be improved on, but speed is important: 1423f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1424a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < sizeof(*key)/sizeof(GLuint); i++) 1425a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell hash ^= ikey[i]; 1426f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1427a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return hash; 1428a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1429f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1430a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) 1431a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1432a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 1433a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct state_key *key; 1434a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash; 1435f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1436a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->VertexProgram._Enabled) 1437a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return; 1438f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1439a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Grab all the relevent state and put it in a single structure: 1440f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1441a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key = make_state_key(ctx); 1442a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell hash = hash_key(key); 1443f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1444a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Look for an already-prepared program for this state: 1445f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1446a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell ctx->_TnlProgram = (struct vertex_program *) 1447a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell search_cache( tnl->vp_cache, hash, key, sizeof(key) ); 1448a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1449a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* OK, we'll have to build a new one: 1450a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1451a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!ctx->_TnlProgram) { 1452a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (0) 1453a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_printf("Build new TNL program\n"); 1454dbeea25bb834479a29712100888c862348112018Keith Whitwell 1455a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell ctx->_TnlProgram = (struct vertex_program *) 1456a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); 1457dbeea25bb834479a29712100888c862348112018Keith Whitwell 1458a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell create_new_program( key, ctx->_TnlProgram, 1459a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell ctx->Const.MaxVertexProgramTemps ); 1460a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1461a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell cache_item(&tnl->vp_cache, hash, key, ctx->_TnlProgram ); 14625a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell } 1463a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell else { 1464a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (0) 1465a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_printf("Found existing TNL program for key %x\n", hash); 1466a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1467a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1468a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Need a BindProgram callback for the driver? 1469a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1470a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1471a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1472a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1473a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_ProgramCacheDestroy( GLcontext *ctx ) 1474a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1475a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 1476a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct tnl_cache *a, *tmp; 1477a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1478a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (a = tnl->vp_cache ; a; a = tmp) { 1479a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell tmp = a->next; 1480a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell FREE(a->key); 1481a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell FREE(a->data); 1482a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell FREE(a); 1483dbeea25bb834479a29712100888c862348112018Keith Whitwell } 1484f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1485