t_vp_build.c revision f069e5e412eebabe64286d35598173caac5c132e
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 20f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 24f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 25f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/** 26f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * \file t_vp_build.c 27f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Create a vertex program to execute the current fixed function T&L pipeline. 28f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * \author Keith Whitwell 29f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 30f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 31f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 32f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include <strings.h> 33f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 34f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "glheader.h" 35f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "macros.h" 36f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "enums.h" 37f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_context.h" 38f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_vp_build.h" 39f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 40f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/program.h" 41f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/nvvertprog.h" 42f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/arbvertparse.h" 43f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 44f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 45f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Very useful debugging tool - produces annotated listing of 46f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * generated program with line/function references for each 47f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * instruction back into this file: 48f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 49f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define DISASSEM 1 50f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 51f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Use uregs to represent registers internally, translate to Mesa's 52f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * expected formats on emit. 53f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 54f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * NOTE: These are passed by value extensively in this file rather 55f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * than as usual by pointer reference. If this disturbs you, try 56f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * remembering they are just 32bits in size. 57f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 58f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * GCC is smart enough to deal with these dword-sized structures in 59f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * much the same way as if I had defined them as dwords and was using 60f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * macros to access and set the fields. This is much nicer and easier 61f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * to evolve. 62f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 63f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct ureg { 64f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint file:4; 65f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint idx:8; 66f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint negate:1; 67f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint swz:12; 68f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint pad:7; 69f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 70f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 71f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 72f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct tnl_program { 73f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLcontext *ctx; 74f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct vertex_program *program; 75f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 76f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint temp_flag; 77f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint temp_reserved; 78f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 79f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position; 80f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position_normalized; 81f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_normal; 82f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg identity; 83f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 84f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint materials; 85f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint color_materials; 86f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 87f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 88f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 89f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellconst static struct ureg undef = { 90f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell ~0, 91f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell ~0, 92f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 93f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 94f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0 95f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 96f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 97f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Local shorthand: 98f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 99f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define X SWIZZLE_X 100f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Y SWIZZLE_Y 101f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Z SWIZZLE_Z 102f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define W SWIZZLE_W 103f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 104f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 105f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Construct a ureg: 106f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 107f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx) 108f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 109f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg; 110f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.file = file; 111f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.idx = idx; 112f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate = 0; 113f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = SWIZZLE_NOOP; 114f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.pad = 0; 115f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 116f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 117f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 118f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 119f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 120f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg negate( struct ureg reg ) 121f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 122f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate ^= 1; 123f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 124f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 125f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 126f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 127f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 128f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 129f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 130f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, y), 131f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, z), 132f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, w)); 133f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 134f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 135f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 136f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 137f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 138f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 139f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return swizzle(reg, x, x, x, x); 140f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 141f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 142f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_temp( struct tnl_program *p ) 143f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 144f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell int bit = ffs( ~p->temp_flag ); 145f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!bit) { 146f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell fprintf(stderr, "%s: out of temporaries\n", __FILE__); 147f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell exit(1); 148f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 149f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 150f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_flag |= 1<<(bit-1); 151f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_TEMPORARY, bit-1); 152f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 153f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 154f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg reserve_temp( struct tnl_program *p ) 155f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 156f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp( p ); 157f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_reserved |= 1<<temp.idx; 158f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 159f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 160f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 161f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temp( struct tnl_program *p, struct ureg reg ) 162f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 163f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY) { 164f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_flag &= ~(1<<reg.idx); 165f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_flag |= p->temp_reserved; /* can't release reserved temps */ 166f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 167f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 168f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 169f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temps( struct tnl_program *p ) 170f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 171f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_flag = p->temp_reserved; 172f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 173f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 174f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 175f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 176f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_input( struct tnl_program *p, GLuint input ) 177f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 178f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->program->InputsRead |= (1<<input); 179f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_INPUT, input); 180f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 181f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 182f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_output( struct tnl_program *p, GLuint output ) 183f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 184f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->program->OutputsWritten |= (1<<output); 185f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_OUTPUT, output); 186f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 187f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 188f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_const4f( struct tnl_program *p, 189f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s0, 190f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s1, 191f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s2, 192f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s3) 193f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 194f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat values[4]; 195f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint idx; 196f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[0] = s0; 197f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[1] = s1; 198f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[2] = s2; 199f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[3] = s3; 200f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell idx = _mesa_add_unnamed_constant( p->program->Parameters, values ); 201f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 202f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 203f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 204f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 205f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 206f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 207f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 208f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLboolean is_undef( struct ureg reg ) 209f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 210f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg.file == 0xf; 211f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 212f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 213f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_identity_param( struct tnl_program *p ) 214f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 215f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->identity)) 216f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->identity = register_const4f(p, 0,0,0,1); 217f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 218f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->identity; 219f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 220f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 221f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_param6( struct tnl_program *p, 222f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s0, 223f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s1, 224f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s2, 225f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s3, 226f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s4, 227f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s5) 228f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 229f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint tokens[6]; 230f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint idx; 231f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[0] = s0; 232f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[1] = s1; 233f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[2] = s2; 234f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[3] = s3; 235f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[4] = s4; 236f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[5] = s5; 237f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell idx = _mesa_add_state_reference( p->program->Parameters, tokens ); 238f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 239f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 240f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 242f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0) 243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0) 244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0) 245f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0) 246f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 247f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 248f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void register_matrix_param6( struct tnl_program *p, 249f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s0, 250f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s1, 251f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s2, 252f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s3, 253f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s4, 254f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s5, 255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg *matrix ) 256f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i; 258f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 259f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* This is a bit sad as the support is there to pull the whole 260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * matrix out in one go: 261f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 262f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i <= s4 - s3; i++) 263f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 ); 264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 265f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 266f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 267f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_arg( struct vp_src_register *src, 268f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg ) 269f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 270f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->File = reg.file; 271f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Index = reg.idx; 272f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Swizzle = reg.swz; 273f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Negate = reg.negate; 274f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->RelAddr = 0; 275f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->pad = 0; 276f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 277f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 278f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_dst( struct vp_dst_register *dst, 279f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg, GLuint mask ) 280f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 281f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->File = reg.file; 282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->Index = reg.idx; 283f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->WriteMask = mask ? mask : WRITEMASK_XYZW; /* allow zero as a shorthand for xyzw */ 284f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->pad = 0; 285f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 286f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 287f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void debug_insn( struct vp_instruction *inst, const char *fn, GLuint line ) 288f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 289f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#if DISASSEM 290f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell static const char *last_fn; 291f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 292f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (fn != last_fn) { 293f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell last_fn = fn; 294f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_printf("%s:\n", fn); 295f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 296f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 297f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_printf("%d:\t", line); 298f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_debug_vp_inst(1, inst); 299f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#endif 300f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 301f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 302f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 303f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_op3fn(struct tnl_program *p, 304f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint op, 305f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 306f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint mask, 307f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src0, 308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src1, 309f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src2, 310f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const char *fn, 311f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint line) 312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr = p->program->Base.NumInstructions++; 314f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct vp_instruction *inst = &p->program->Instructions[nr]; 315f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell inst->Opcode = op; 317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 319f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_dst( &inst->DstReg, dest, mask ); 323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 324f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell debug_insn(inst, fn, line); 325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 329f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define emit_op3(p, op, dst, mask, src0, src1, src2) emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__) 330f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define emit_op2(p, op, dst, mask, src0, src1) emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__) 331f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define emit_op1(p, op, dst, mask, src0) emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__) 332f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 333f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 334f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_temp( struct tnl_program *p, struct ureg reg ) 335f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 336f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY && 337f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell !(p->temp_reserved & (1<<reg.idx))) 338f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 339f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 340f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp(p); 341f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, temp, 0, reg); 342f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 343f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 344f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 345f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 346f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 347f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Currently no tracking performed of input/output/register size or 348f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * active elements. Could be used to reduce these operations, as 349f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * could the matrix type. 350f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 351f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec4( struct tnl_program *p, 352f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 353f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 354f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 356f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]); 357f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]); 358f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]); 359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]); 360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 362f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 363f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec3( struct tnl_program *p, 364f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 365f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 366f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 367f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 368f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]); 369f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]); 370f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]); 371f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 372f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 373f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 374f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_normalize_vec3( struct tnl_program *p, 375f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 376f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src ) 377f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 378f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 379f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, src, src); 380f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RSQ, tmp, 0, tmp); 381f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, dest, 0, src, tmp); 382f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 383f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 384f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 385f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position( struct tnl_program *p ) 386f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 387f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position)) { 388f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 389f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg modelview[4]; 390f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 391f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, 0, modelview ); 392f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position = reserve_temp(p); 393f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 394f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_matrix_transform_vec4( p, p->eye_position, modelview, pos ); 395f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 396f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 397f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position; 398f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 399f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 400f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 401f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position_normalized( struct tnl_program *p ) 402f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 403f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position_normalized)) { 404f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 405f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position_normalized = reserve_temp(p); 406f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, p->eye_position_normalized, eye); 407f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 408f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 409f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position_normalized; 410f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 411f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 412f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 413f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_normal( struct tnl_program *p ) 414f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 415f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_normal)) { 416f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); 417f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvinv[3]; 418f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 419f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, STATE_MATRIX_INVTRANS, mvinv ); 420f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 421f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_normal = reserve_temp(p); 422f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 423f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Transform to eye space: 424f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 425f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal ); 426f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 427f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Normalize/Rescale: 428f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 429f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->ctx->Transform.Normalize) { 430f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3( p, p->eye_normal, p->eye_normal ); 431f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 432f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else if (p->ctx->Transform.RescaleNormals) { 433f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg rescale = register_param2(p, STATE_INTERNAL, STATE_NORMAL_SCALE); 434f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2( p, VP_OPCODE_MUL, p->eye_normal, 0, normal, swizzle1(rescale, X)); 435f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 436f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 437f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 438f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_normal; 439f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 440f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 441f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 442f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 443f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_hpos( struct tnl_program *p ) 444f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 445f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 446f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); 447f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvp[4]; 448f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 449f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, 0, mvp ); 450f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_matrix_transform_vec4( p, hpos, mvp, pos ); 451f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 452f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 453f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 454f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLuint material_attrib( GLuint side, GLuint property ) 455f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 456f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return _TNL_ATTRIB_MAT_FRONT_AMBIENT + (property - STATE_AMBIENT) * 2 + side; 457f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 458f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 459f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void set_material_flags( struct tnl_program *p ) 460f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 461f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLcontext *ctx = p->ctx; 462f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 463f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i; 464f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 465f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->color_materials = 0; 466f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 0; 467f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 468f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Light.ColorMaterialEnabled) { 469f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 470f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->color_materials = 471f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell ctx->Light.ColorMaterialBitmask << _TNL_ATTRIB_MAT_FRONT_AMBIENT; 472f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 473f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 474f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT ; i < _TNL_ATTRIB_INDEX ; i++) 475f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (tnl->vb.AttribPtr[i]->stride) 476f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials |= 1<<i; 477f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 478f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 479f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 480f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_material( struct tnl_program *p, GLuint side, GLuint property ) 481f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 482f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 483f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 484f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->color_materials & (1<<attrib)) 485f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_input(p, VERT_ATTRIB_COLOR0); 486f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else if (p->materials & (1<<attrib)) 487f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_input( p, attrib ); 488f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 489f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param3( p, STATE_MATERIAL, side, property ); 490f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 491f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 492f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define SCENE_COLOR_BITS(side) (( _TNL_BIT_MAT_FRONT_EMISSION | \ 493f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _TNL_BIT_MAT_FRONT_AMBIENT | \ 494f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _TNL_BIT_MAT_FRONT_DIFFUSE) << (side)) 495f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 496f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Either return a precalculated constant value or emit code to 497f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * calculate these values dynamically in the case where material calls 498f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * are present between begin/end pairs. 499f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 500f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Probably want to shift this to the program compilation phase - if 501f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * we always emitted the calculation here, a smart compiler could 502f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * detect that it was constant (given a certain set of inputs), and 503f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * lift it out of the main loop. That way the programs created here 504f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * would be independent of the vertex_buffer details. 505f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 506f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) 507f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 508f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & SCENE_COLOR_BITS(side)) { 509f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg lightmodel_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); 510f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_emission = get_material(p, side, STATE_EMISSION); 511f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); 512f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); 513f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = make_temp(p, material_diffuse); 514f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, tmp, WRITEMASK_XYZ, lightmodel_ambient, material_ambient, material_emission); 515f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 516f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 517f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 518f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side ); 519f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 520f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 521f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 522f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_lightprod( struct tnl_program *p, GLuint light, GLuint side, GLuint property ) 523f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 524f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 525f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & (1<<attrib)) { 526f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg light_value = register_param3(p, STATE_LIGHT, light, property); 527f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_value = get_material(p, side, property); 528f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 529f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, light_value, material_value); 530f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 531f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 532f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 533f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param4(p, STATE_LIGHTPROD, light, side, property); 534f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 535f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 536f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 537f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 538f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 539f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Need to add some addtional parameters to allow lighting in object 540f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye 541f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space lighting. 542f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 543f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_lighting( struct tnl_program *p ) 544f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 545f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLcontext *ctx = p->ctx; 546f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const GLboolean twoside = ctx->Light.Model.TwoSide; 547f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const GLboolean separate = (ctx->Light.Model.ColorControl == 548f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GL_SEPARATE_SPECULAR_COLOR); 549f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr_lights = 0, count = 0; 550f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 551f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg lit = get_temp(p); 552f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dots = get_temp(p); 553f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _col0 = undef, _col1 = undef; 554f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _bfc0 = undef, _bfc1 = undef; 555f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i; 556f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 557f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) 558f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Light.Light[i].Enabled) 559f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell nr_lights++; 560f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 561f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell set_material_flags(p); 562f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 563f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 564f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 0, STATE_SHININESS); 565f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); 566f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 567f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 568f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col0 = make_temp(p, get_scenecolor(p, 0)); 569f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 570f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = make_temp(p, get_identity_param(p)); 571f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 572f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = _col0; 573f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 574f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 575f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 576f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 577f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 1, STATE_SHININESS); 578f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, dots, WRITEMASK_Z, negate(swizzle1(shininess,X))); 579f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 580f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 581f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc0 = make_temp(p, get_scenecolor(p, 1)); 582f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 583f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = make_temp(p, get_identity_param(p)); 584f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 585f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = _bfc0; 586f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 587f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 588f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 589f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct gl_light *light = &ctx->Light.Light[i]; 590f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 591f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (light->Enabled) { 592f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg half = undef; 593f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg att = undef, VPpli = undef; 594f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 595f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell count++; 596f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 597f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (light->EyePosition[3] == 0) { 598f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Can used precomputed constants in this case: 599f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 600f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell VPpli = register_param3(p, STATE_LIGHT, i, STATE_POSITION_NORMALIZED); 601f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell half = register_param3(p, STATE_LIGHT, i, STATE_HALF); 602f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 603f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Spot attenuation maybe applies to this case? Could precompute if so? */ 604f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 605f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 606f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg Ppli = register_param3(p, STATE_LIGHT, i, STATE_POSITION); 607f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg V = get_eye_position(p); 608f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dst = get_temp(p); 609f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 610f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell VPpli = get_temp(p); 611f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell half = get_temp(p); 612f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 613f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calulate VPpli vector 614f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 615f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_SUB, VPpli, 0, Ppli, V); 616f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 617f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Normalize VPpli. The dst value also used in 618f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * attenuation below. 619f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 620f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dst, 0, VPpli, VPpli); 621f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RSQ, dst, 0, dst); 622f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, VPpli, 0, VPpli, dst); 623f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 624f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 625f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate attenuation: 626f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 627f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (light->SpotCutoff != 180.0 || 628f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell light->ConstantAttenuation != 1.0 || 629f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell light->LinearAttenuation != 1.0 || 630f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell light->QuadraticAttenuation != 1.0) { 631f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 632f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg attenuation = register_param3(p, STATE_LIGHT, i, STATE_ATTENUATION); 633f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell att = get_temp(p); 634f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 635f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate spot attenuation: 636f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 637f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (light->SpotCutoff != 180.0F) { 638f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg spot_dir = register_param3(p, STATE_LIGHT, i, STATE_SPOT_DIRECTION); 639f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg spot = get_temp(p); 640f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg slt = get_temp(p); 641f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 642f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3( p, spot, spot_dir ); /* XXX: precompute! */ 643f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, spot, 0, negate(VPpli), spot_dir); 644f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_SLT, slt, 0, swizzle1(spot_dir,W), spot); 645f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); 646f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, att, 0, slt, spot); 647f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 648f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, spot); 649f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, slt); 650f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 651f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 652f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate distance attenuation: 653f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 654f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (light->ConstantAttenuation != 1.0 || 655f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell light->LinearAttenuation != 1.0 || 656f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell light->QuadraticAttenuation != 1.0) { 657f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 658f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RCP, dst, WRITEMASK_YZ, dst); /* 1/d,d,d,1/d */ 659f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, dst, WRITEMASK_XZ, dst, swizzle1(dst,Y)); /* 1,d,d*d,1/d */ 660f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dst, 0, attenuation, dst); /* 1/dist-atten */ 661f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 662f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (light->SpotCutoff != 180.0F) { 663f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RCP, dst, 0, dst); /* dist-atten */ 664f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, att, 0, dst, att); /* spot-atten * dist-atten */ 665f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 666f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RCP, att, 0, dst); /* dist-atten */ 667f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 668f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 669f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 670f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 671f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 672f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate viewer direction, or use infinite viewer: 673f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 674f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Light.Model.LocalViewer) { 675f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 676f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_SUB, half, 0, VPpli, eye_hat); 677f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 678f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 679f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); /* 0,0,1,0 */ 680f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_ADD, half, 0, VPpli, z_dir); 681f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 682f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 683f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, half, half); 684f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 685f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, dst); 686f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 687f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 688f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate dot products: 689f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 690f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); 691f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, dots, WRITEMASK_Y, normal, half); 692f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 693f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 694f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Front face lighting: 695f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 696f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 697f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); 698f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); 699f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); 700f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 701f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 702f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_LIT, lit, 0, dots); 703f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 704f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 705f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, lit, 0, lit, att); 706f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 707f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 708f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 709f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 710f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_COL0 ); 711f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL1 ); 712f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 713f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 714f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 715f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL0 ); 716f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 717f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 718f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 719f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _col1; 720f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 721f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 722f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); 723f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res0, 0, swizzle1(lit,Y), diffuse, _col0); 724f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res1, 0, swizzle1(lit,Z), specular, _col1); 725f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 726f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 727f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 728f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 729f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 730f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 731f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Back face lighting: 732f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 733f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 734f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); 735f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); 736f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); 737f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 738f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 739f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_LIT, lit, 0, negate(swizzle(dots,X,Y,W,Z))); 740f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 741f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 742f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, lit, 0, lit, att); 743f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 744f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 745f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 746f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_BFC0 ); 747f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC1 ); 748f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 749f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 750f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 751f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC0 ); 752f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 753f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 754f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 755f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _bfc1; 756f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 757f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 758f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 759f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); 760f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res0, 0, swizzle1(lit,Y), diffuse, _bfc0); 761f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, res1, 0, swizzle1(lit,Z), specular, _bfc1); 762f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 763f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 764f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 765f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 766f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 767f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 768f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, half); 769f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, VPpli); 770f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, att); 771f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 772f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 773f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 774f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps( p ); 775f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 776f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 777f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 778f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_fog( struct tnl_program *p ) 779f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 780f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLcontext *ctx = p->ctx; 781f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 782f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg fog = register_output(p, VERT_RESULT_FOGC); 783f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg input; 784f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 785f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) { 786f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(get_eye_position(p), Z); 787f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 788f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 789f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); 790f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 791f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 792f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (tnl->_DoVertexFog) { 793f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg params = register_param1(p, STATE_FOG_PARAMS); 794f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 795f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 796f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell switch (ctx->Fog.Mode) { 797f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_LINEAR: { 798f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg id = get_identity_param(p); 799f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_SUB, tmp, 0, swizzle1(params,Z), input); 800f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, swizzle1(params,W)); 801f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ 802f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); /* saturate */ 803f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 804f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 805f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_EXP: 806f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_ABS, tmp, 0, input); 807f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, swizzle1(params,X)); 808f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_POW, fog, WRITEMASK_X, register_const1f(p, M_E), negate(tmp)); 809f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 810f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_EXP2: 811f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, input, swizzle1(params,X)); 812f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, tmp); 813f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_POW, fog, WRITEMASK_X, register_const1f(p, M_E), negate(tmp)); 814f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 815f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 816f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 817f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 818f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 819f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 820f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* results = incoming fog coords (compute fog per-fragment later) 821f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 822f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * KW: Is it really necessary to do anything in this case? 823f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 824f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, fog, WRITEMASK_X, input); 825f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 826f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 827f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 828f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 829f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 830f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_texture_transform( struct tnl_program *p ) 831f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 832f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLcontext *ctx = p->ctx; 833f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i, j; 834f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 835f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 836f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 837f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint texmat_enabled = ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i); 838f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); 839f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 840f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texUnit->TexGenEnabled || texmat_enabled) { 841f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg out_texgen = undef; 842f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 843f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texUnit->TexGenEnabled) { 844f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint copy_mask = 0; 845f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint sphere_mask = 0; 846f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint reflect_mask = 0; 847f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint normal_mask = 0; 848f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint modes[4]; 849f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 850f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) 851f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = get_temp(p); 852f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 853f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = out; 854f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 855f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell modes[0] = texUnit->GenModeS; 856f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell modes[1] = texUnit->GenModeT; 857f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell modes[2] = texUnit->GenModeR; 858f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell modes[3] = texUnit->GenModeQ; 859f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 860f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (j = 0; j < 4; j++) { 861f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texUnit->TexGenEnabled & (1<<j)) { 862f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell switch (modes[j]) { 863f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_OBJECT_LINEAR: { 864f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg obj = register_input(p, VERT_ATTRIB_POS); 865f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_OBJECT_S + j); 866f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, out_texgen, WRITEMASK_X << j, obj, plane ); 867f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 868f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 869f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_EYE_LINEAR: { 870f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 871f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_EYE_S + j); 872f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP4, out_texgen, WRITEMASK_X << j, eye, plane ); 873f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 874f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 875f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_SPHERE_MAP: 876f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell sphere_mask |= WRITEMASK_X << j; 877f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 878f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_REFLECTION_MAP_NV: 879f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reflect_mask |= WRITEMASK_X << j; 880f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 881f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell case GL_NORMAL_MAP_NV: 882f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell normal_mask |= WRITEMASK_X << j; 883f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 884f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 885f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 886f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 887f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell copy_mask |= WRITEMASK_X << j; 888f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 889f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 890f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 891f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (sphere_mask) { 892f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 893f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 894f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 895f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg half = register_const1f(p, .5); 896f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg r = get_temp(p); 897f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg inv_m = get_temp(p); 898f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 899f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, normal, eye_hat); /* n.u */ 900f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_ADD, tmp, 0, tmp, tmp); /* 2n.u */ 901f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat); /* (-2n.u)n + u */ 902f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_ADD, tmp, 0, r, swizzle(get_identity_param(p),X,Y,W,Z)); /* r + 0,0,1 */ 903f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, tmp, tmp); /* rx^2 + ry^2 + (rz+1)^2 */ 904f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RSQ, tmp, 0, tmp); /* 2/m */ 905f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, inv_m, 0, tmp, swizzle1(half,X)); /* 1/m */ 906f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, out_texgen, sphere_mask, r, inv_m, swizzle1(half,X)); /* r/m + 1/2 */ 907f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 908f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 909f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, r); 910f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, inv_m); 911f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 912f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 913f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Could duplicate the above calculations, but it would be 914f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * a fairly odd state for someone to set (both sphere and 915f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * reflection active for different texture coordinate 916f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * components. Of course - if two texture units enable 917f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * reflect and/or sphere, things start to tilt in favour 918f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * of seperating this out: 919f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 920f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reflect_mask) { 921f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 922f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 923f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 924f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 925f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, tmp, 0, normal, eye_hat); 926f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_ADD, tmp, 0, tmp, tmp); 927f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op3(p, VP_OPCODE_MAD, out_texgen, reflect_mask, negate(tmp), normal, eye_hat); 928f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 929f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 930f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (normal_mask) { 931f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 932f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, out_texgen, normal_mask, normal ); 933f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 934f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 935f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (copy_mask) { 936f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); 937f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, out_texgen, copy_mask, in ); 938f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 939f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 940f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 941f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) { 942f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg texmat[4]; 943f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg in = !is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i); 944f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 0, 3, 0, texmat ); 945f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_matrix_transform_vec4( p, out, texmat, in ); 946f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 947f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 948f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps(p); 949f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 950f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 951f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 952f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 953f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 954f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Seems like it could be tighter: 955f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 956f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_pointsize( struct tnl_program *p ) 957f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 958f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 959f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg state_size = register_param1( p, STATE_POINT_SIZE ); 960f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg state_attenuation = register_param1( p, STATE_POINT_ATTENUATION ); 961f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg out = register_output( p, VERT_RESULT_PSIZ ); 962f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ut = get_temp(p); 963f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 964f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* 1, -Z, Z * Z, 1 */ 965f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_MOV, ut, 0, swizzle1(get_identity_param(p), W)); 966f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, ut, WRITEMASK_YZ, ut, negate(swizzle1(eye, Z))); 967f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, ut, WRITEMASK_Z, ut, negate(swizzle1(eye, Z))); 968f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 969f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 970f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* p1 + p2 * dst + p3 * dst * dst, 0 */ 971f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_DP3, ut, 0, ut, state_attenuation); 972f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 973f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* 1 / factor */ 974f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(p, VP_OPCODE_RCP, ut, 0, ut ); 975f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 976f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* out = pointSize / factor */ 977f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op2(p, VP_OPCODE_MUL, out, WRITEMASK_X, ut, state_size); 978f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 979f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ut); 980f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 981f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 982f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 983f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 984f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellvoid _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) 985f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 986f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct tnl_program p; 987f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 988f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->VertexProgram._Enabled) 989f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return; 990f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 991f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell memset(&p, 0, sizeof(p)); 992f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.ctx = ctx; 993f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program = &ctx->_TnlProgram; 994f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 995f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position = undef; 996f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position_normalized = undef; 997f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_normal = undef; 998f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.identity = undef; 999f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1000f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.temp_flag = 0; 1001f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.temp_reserved = ~((1<<MAX_NV_VERTEX_PROGRAM_TEMPS)-1); 1002f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1003f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p.program->Instructions == NULL) { 1004f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Instructions = MALLOC(sizeof(struct vp_instruction) * 100); 1005f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1006f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1007f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Initialize the arb_program struct */ 1008f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.String = 0; 1009f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumInstructions = 1010f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumTemporaries = 1011f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumParameters = 1012f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1013f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p.program->Parameters) 1014f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_free_parameter_list(p.program->Parameters); 1015f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Parameters = _mesa_new_parameter_list (); 1016f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->InputsRead = 0; 1017f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->OutputsWritten = 0; 1018f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1019f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Emit the program, starting with modelviewproject: 1020f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1021f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell build_hpos(&p); 1022f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1023f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Lighting calculations: 1024f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1025f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Light.Enabled) 1026f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell build_lighting(&p); 1027f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1028f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Fog.Enabled) 1029f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell build_fog(&p); 1030f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1031f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Texture._TexGenEnabled || ctx->Texture._TexMatEnabled) 1032f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell build_texture_transform(&p); 1033f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1034f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (ctx->Point._Attenuated) 1035f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell build_pointsize(&p); 1036f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1037f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1038f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Finish up: 1039f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1040f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_op1(&p, VP_OPCODE_END, undef, 0, undef); 1041f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1042f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Disassemble: 1043f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1044f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (DISASSEM) { 1045f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _mesa_printf ("\n"); 1046f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1047f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1048