t_vp_build.c revision 5f534aa1e2c53360bb1ae42fb196e41aa29d0d3d
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 <strings.h>
34f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
35f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "glheader.h"
36f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "macros.h"
37f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "enums.h"
38f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_context.h"
39f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_vp_build.h"
40f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
41f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/program.h"
42f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/nvvertprog.h"
43f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "shader/arbvertparse.h"
44f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
45f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
46f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Very useful debugging tool - produces annotated listing of
47f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * generated program with line/function references for each
48f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * instruction back into this file:
49f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
506f973f33679e034b7cb63806f1ddfabdbdd70123Keith Whitwell#define DISASSEM 0
51f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
52f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Use uregs to represent registers internally, translate to Mesa's
53f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * expected formats on emit.
54f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell *
55f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * NOTE: These are passed by value extensively in this file rather
56f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * than as usual by pointer reference.  If this disturbs you, try
57f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * remembering they are just 32bits in size.
58f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell *
59f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * GCC is smart enough to deal with these dword-sized structures in
60f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * much the same way as if I had defined them as dwords and was using
61f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * macros to access and set the fields.  This is much nicer and easier
62f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * to evolve.
63f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
64f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct ureg {
65f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint file:4;
66f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint idx:8;
67f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint negate:1;
68f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint swz:12;
69f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint pad:7;
70f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell};
71f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
72f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
73f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct tnl_program {
74f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLcontext *ctx;
75f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct vertex_program *program;
76f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
77f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint temp_flag;
78f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint temp_reserved;
79f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
80f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg eye_position;
81f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg eye_position_normalized;
82f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg eye_normal;
83f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg identity;
84f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
85f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint materials;
86f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint color_materials;
87f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell};
88f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
89f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
90f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellconst static struct ureg undef = {
91f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   ~0,
92f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   ~0,
93f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   0,
94f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   0,
95f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   0
96f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell};
97f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
98f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Local shorthand:
99f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
100f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define X    SWIZZLE_X
101f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Y    SWIZZLE_Y
102f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Z    SWIZZLE_Z
103f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define W    SWIZZLE_W
104f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
105f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
106f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Construct a ureg:
107f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
108f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx)
109f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
110f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg reg;
111f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   reg.file = file;
112f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   reg.idx = idx;
113f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   reg.negate = 0;
114f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   reg.swz = SWIZZLE_NOOP;
115f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   reg.pad = 0;
116f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return reg;
117f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
118f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
119f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
120f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
121f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg negate( struct ureg reg )
122f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
123f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   reg.negate ^= 1;
124f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return reg;
125f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
126f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
127f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
128f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w )
129f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
130f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x),
131f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			   GET_SWZ(reg.swz, y),
132f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			   GET_SWZ(reg.swz, z),
133f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			   GET_SWZ(reg.swz, w));
134f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
135f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return reg;
136f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
137f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
138f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x )
139f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
140f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return swizzle(reg, x, x, x, x);
141f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
142f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
143f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_temp( struct tnl_program *p )
144f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
145f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   int bit = ffs( ~p->temp_flag );
146f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (!bit) {
147f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      fprintf(stderr, "%s: out of temporaries\n", __FILE__);
148f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      exit(1);
149f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
150f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
151f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p->temp_flag |= 1<<(bit-1);
152f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return make_ureg(PROGRAM_TEMPORARY, bit-1);
153f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
154f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
155f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg reserve_temp( struct tnl_program *p )
156f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
157f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg temp = get_temp( p );
158f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p->temp_reserved |= 1<<temp.idx;
159f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return temp;
160f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
161f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
162f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temp( struct tnl_program *p, struct ureg reg )
163f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
164f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (reg.file == PROGRAM_TEMPORARY) {
165f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p->temp_flag &= ~(1<<reg.idx);
166f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p->temp_flag |= p->temp_reserved; /* can't release reserved temps */
167f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
168f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
169f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
170f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temps( struct tnl_program *p )
171f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
172f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p->temp_flag = p->temp_reserved;
173f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
174f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
175f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
176f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
177f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_input( struct tnl_program *p, GLuint input )
178f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
179f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p->program->InputsRead |= (1<<input);
180f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return make_ureg(PROGRAM_INPUT, input);
181f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
182f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
183f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_output( struct tnl_program *p, GLuint output )
184f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
185f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p->program->OutputsWritten |= (1<<output);
186f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return make_ureg(PROGRAM_OUTPUT, output);
187f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
188f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
189f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_const4f( struct tnl_program *p,
190f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			      GLfloat s0,
191f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			      GLfloat s1,
192f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			      GLfloat s2,
193f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			      GLfloat s3)
194f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
195f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLfloat values[4];
196f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint idx;
197f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   values[0] = s0;
198f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   values[1] = s1;
199f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   values[2] = s2;
200f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   values[3] = s3;
201f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   idx = _mesa_add_unnamed_constant( p->program->Parameters, values );
202f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return make_ureg(PROGRAM_STATE_VAR, idx);
203f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
204f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
205f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const1f(p, s0)         register_const4f(p, s0, 0, 0, 1)
206f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const2f(p, s0, s1)     register_const4f(p, s0, s1, 0, 1)
207f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)
208f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
209f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLboolean is_undef( struct ureg reg )
210f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
211f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return reg.file == 0xf;
212f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
213f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
214f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_identity_param( struct tnl_program *p )
215f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
216f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (is_undef(p->identity))
217f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p->identity = register_const4f(p, 0,0,0,1);
218f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
219f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return p->identity;
220f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
221f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
222f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_param6( struct tnl_program *p,
223f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   GLint s0,
224f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   GLint s1,
225f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   GLint s2,
226f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   GLint s3,
227f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   GLint s4,
228f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   GLint s5)
229f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
230f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLint tokens[6];
231f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint idx;
232f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   tokens[0] = s0;
233f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   tokens[1] = s1;
234f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   tokens[2] = s2;
235f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   tokens[3] = s3;
236f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   tokens[4] = s4;
237f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   tokens[5] = s5;
238f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   idx = _mesa_add_state_reference( p->program->Parameters, tokens );
239f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return make_ureg(PROGRAM_STATE_VAR, idx);
240f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
242f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param1(p,s0)          register_param6(p,s0,0,0,0,0,0)
244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param2(p,s0,s1)       register_param6(p,s0,s1,0,0,0,0)
245f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param3(p,s0,s1,s2)    register_param6(p,s0,s1,s2,0,0,0)
246f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
247f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
248f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
249f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void register_matrix_param6( struct tnl_program *p,
250f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				    GLint s0,
251f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				    GLint s1,
252f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				    GLint s2,
253f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				    GLint s3,
254f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				    GLint s4,
255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				    GLint s5,
256f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				    struct ureg *matrix )
257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
258f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint i;
259f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* This is a bit sad as the support is there to pull the whole
261f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell    * matrix out in one go:
262f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell    */
263f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   for (i = 0; i <= s4 - s3; i++)
264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 );
265f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
266f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
267f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
268f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_arg( struct vp_src_register *src,
269f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		      struct ureg reg )
270f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
271f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   src->File = reg.file;
272f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   src->Index = reg.idx;
273f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   src->Swizzle = reg.swz;
274f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   src->Negate = reg.negate;
275f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   src->RelAddr = 0;
276f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   src->pad = 0;
277f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
278f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
279f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_dst( struct vp_dst_register *dst,
280f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		      struct ureg reg, GLuint mask )
281f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   dst->File = reg.file;
283f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   dst->Index = reg.idx;
2845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* allow zero as a shorthand for xyzw */
2855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   dst->WriteMask = mask ? mask : WRITEMASK_XYZW;
286f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   dst->pad = 0;
287f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
288f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
2895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void debug_insn( struct vp_instruction *inst, const char *fn,
2905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			GLuint line )
291f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
292f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#if DISASSEM
293f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   static const char *last_fn;
294f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
295f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (fn != last_fn) {
296f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      last_fn = fn;
297f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      _mesa_printf("%s:\n", fn);
298f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
299f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
300f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   _mesa_printf("%d:\t", line);
301f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   _mesa_debug_vp_inst(1, inst);
302f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#endif
303f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
304f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
305f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
306f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_op3fn(struct tnl_program *p,
307f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       GLuint op,
308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       struct ureg dest,
309f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       GLuint mask,
310f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       struct ureg src0,
311f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       struct ureg src1,
312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       struct ureg src2,
313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       const char *fn,
314f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		       GLuint line)
315f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint nr = p->program->Base.NumInstructions++;
317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct vp_instruction *inst = &p->program->Instructions[nr];
318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
319f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   inst->Opcode = op;
320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_arg( &inst->SrcReg[0], src0 );
322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_arg( &inst->SrcReg[1], src1 );
323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_arg( &inst->SrcReg[2], src2 );
324f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_dst( &inst->DstReg, dest, mask );
326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   debug_insn(inst, fn, line);
328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
329f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
330f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
331f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
3325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op3(p, op, dst, mask, src0, src1, src2) \
3335f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__)
3345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
3355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op2(p, op, dst, mask, src0, src1) \
3365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__)
3375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
3385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op1(p, op, dst, mask, src0) \
3395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__)
340f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
341f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
342f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_temp( struct tnl_program *p, struct ureg reg )
343f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
344f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (reg.file == PROGRAM_TEMPORARY &&
345f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell       !(p->temp_reserved & (1<<reg.idx)))
346f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return reg;
347f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   else {
348f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg temp = get_temp(p);
349f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      emit_op1(p, VP_OPCODE_MOV, temp, 0, reg);
350f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return temp;
351f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
352f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
353f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
354f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Currently no tracking performed of input/output/register size or
356f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * active elements.  Could be used to reduce these operations, as
357f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * could the matrix type.
358f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec4( struct tnl_program *p,
360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell					struct ureg dest,
361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell					const struct ureg *mat,
362f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell					struct ureg src)
363f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
364f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]);
365f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]);
366f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]);
367f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]);
3685f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell}
3695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
3705f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void emit_transpose_matrix_transform_vec4( struct tnl_program *p,
3715f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell						  struct ureg dest,
3725f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell						  const struct ureg *mat,
3735f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell						  struct ureg src)
3745f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{
3755f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg tmp;
3765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
3775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   if (dest.file != PROGRAM_TEMPORARY)
3785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      tmp = get_temp(p);
3795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   else
3805f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      tmp = dest;
381f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
3825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]);
3835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op3(p, VP_OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp);
3845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op3(p, VP_OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp);
3855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op3(p, VP_OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp);
3865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
3875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   if (dest.file != PROGRAM_TEMPORARY)
3885f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      release_temp(p, tmp);
389f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
390f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
391f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec3( struct tnl_program *p,
392f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell					struct ureg dest,
393f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell					const struct ureg *mat,
394f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell					struct ureg src)
395f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
396f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]);
397f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]);
398f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]);
399f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
400f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
401f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
402f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_normalize_vec3( struct tnl_program *p,
403f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				 struct ureg dest,
404f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				 struct ureg src )
405f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
406f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg tmp = get_temp(p);
407f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, tmp, 0, src, src);
408f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op1(p, VP_OPCODE_RSQ, tmp, 0, tmp);
409f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_MUL, dest, 0, src, tmp);
410f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   release_temp(p, tmp);
411f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
412f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
413f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position( struct tnl_program *p )
414f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
415f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (is_undef(p->eye_position)) {
416f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg pos = register_input( p, VERT_ATTRIB_POS );
417f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg modelview[4];
418f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
4195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3,
4205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			      STATE_MATRIX_TRANSPOSE, modelview );
421f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p->eye_position = reserve_temp(p);
422f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
4235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos);
424f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
425f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
426f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return p->eye_position;
427f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
428f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
429f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
430f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position_normalized( struct tnl_program *p )
431f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
432f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (is_undef(p->eye_position_normalized)) {
433f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg eye = get_eye_position(p);
434f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p->eye_position_normalized = reserve_temp(p);
435f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      emit_normalize_vec3(p, p->eye_position_normalized, eye);
436f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
437f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
438f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return p->eye_position_normalized;
439f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
440f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
441f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
442f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_normal( struct tnl_program *p )
443f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
444f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (is_undef(p->eye_normal)) {
445f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL );
446f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg mvinv[3];
447f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
4485f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2,
4495f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			      STATE_MATRIX_INVTRANS, mvinv );
450f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
451f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p->eye_normal = reserve_temp(p);
452f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
453f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      /* Transform to eye space:
454f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell       */
455f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal );
456f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
457f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      /* Normalize/Rescale:
458f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell       */
459f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      if (p->ctx->Transform.Normalize) {
460f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_normalize_vec3( p, p->eye_normal, p->eye_normal );
461f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      }
462f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      else if (p->ctx->Transform.RescaleNormals) {
4635f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 struct ureg rescale = register_param2(p, STATE_INTERNAL,
4645f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell					       STATE_NORMAL_SCALE);
4655f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
4665f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 emit_op2( p, VP_OPCODE_MUL, p->eye_normal, 0, normal,
4675f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell		   swizzle1(rescale, X));
468f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      }
469f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
470f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
471f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   return p->eye_normal;
472f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
473f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
474f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
475f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
476f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_hpos( struct tnl_program *p )
477f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
478f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg pos = register_input( p, VERT_ATTRIB_POS );
479f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg hpos = register_output( p, VERT_RESULT_HPOS );
480f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg mvp[4];
481f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
4825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3,
4835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			   STATE_MATRIX_TRANSPOSE, mvp );
4845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos );
485f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
486f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
487f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
488f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLuint material_attrib( GLuint side, GLuint property )
489f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
4905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   return (_TNL_ATTRIB_MAT_FRONT_AMBIENT +
4915f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	   (property - STATE_AMBIENT) * 2 +
4925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	   side);
493f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
494f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
495f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void set_material_flags( struct tnl_program *p )
496f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
497f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLcontext *ctx = p->ctx;
498f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
499f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint i;
500f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
501f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p->color_materials = 0;
502f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p->materials = 0;
503f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
504f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (ctx->Light.ColorMaterialEnabled) {
505f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p->materials =
506f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 p->color_materials =
507f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 ctx->Light.ColorMaterialBitmask << _TNL_ATTRIB_MAT_FRONT_AMBIENT;
508f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
509f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
510f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT ; i < _TNL_ATTRIB_INDEX ; i++)
511f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      if (tnl->vb.AttribPtr[i]->stride)
512f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 p->materials |= 1<<i;
513f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
514f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
515f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
5165f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_material( struct tnl_program *p, GLuint side,
5175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				 GLuint property )
518f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
519f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint attrib = material_attrib(side, property);
520f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
521f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (p->color_materials & (1<<attrib))
522f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return register_input(p, VERT_ATTRIB_COLOR0);
523f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   else if (p->materials & (1<<attrib))
524f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return register_input( p, attrib );
525f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   else
526f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return register_param3( p, STATE_MATERIAL, side, property );
527f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
528f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
529f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define SCENE_COLOR_BITS(side) (( _TNL_BIT_MAT_FRONT_EMISSION | \
530f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   _TNL_BIT_MAT_FRONT_AMBIENT | \
531f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell				   _TNL_BIT_MAT_FRONT_DIFFUSE) << (side))
532f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
533f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Either return a precalculated constant value or emit code to
534f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * calculate these values dynamically in the case where material calls
535f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * are present between begin/end pairs.
536f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell *
537f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Probably want to shift this to the program compilation phase - if
538f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * we always emitted the calculation here, a smart compiler could
539f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * detect that it was constant (given a certain set of inputs), and
540f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * lift it out of the main loop.  That way the programs created here
541f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * would be independent of the vertex_buffer details.
542f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
543f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_scenecolor( struct tnl_program *p, GLuint side )
544f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
545f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (p->materials & SCENE_COLOR_BITS(side)) {
5465f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT);
547f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg material_emission = get_material(p, side, STATE_EMISSION);
548f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg material_ambient = get_material(p, side, STATE_AMBIENT);
549f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE);
550f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg tmp = make_temp(p, material_diffuse);
5515f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op3(p, VP_OPCODE_MAD, tmp,  WRITEMASK_XYZ, lm_ambient,
5525f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	       material_ambient, material_emission);
553f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return tmp;
554f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
555f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   else
556f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side );
557f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
558f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
559f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
5605f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_lightprod( struct tnl_program *p, GLuint light,
5615f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				  GLuint side, GLuint property )
562f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
563f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint attrib = material_attrib(side, property);
564f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (p->materials & (1<<attrib)) {
5655f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      struct ureg light_value =
5665f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 register_param3(p, STATE_LIGHT, light, property);
567f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg material_value = get_material(p, side, property);
568f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg tmp = get_temp(p);
569f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      emit_op2(p, VP_OPCODE_MUL, tmp,  0, light_value, material_value);
570f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return tmp;
571f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
572f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   else
573f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return register_param4(p, STATE_LIGHTPROD, light, side, property);
574f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
575f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
5765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg calculate_light_attenuation( struct tnl_program *p,
5775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell						GLuint i,
5785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell						struct gl_light *light,
5795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell						struct ureg VPpli,
5805f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell						struct ureg dist )
5815f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{
5825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg attenuation = register_param3(p, STATE_LIGHT, i,
5835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell					     STATE_ATTENUATION);
5845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg att = get_temp(p);
5855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
5865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* Calculate spot attenuation:
5875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    */
5885f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   if (light->SpotCutoff != 180.0F) {
5895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      struct ureg spot_dir = register_param3(p, STATE_LIGHT, i,
5905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell					     STATE_SPOT_DIRECTION);
5915f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      struct ureg spot = get_temp(p);
5925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      struct ureg slt = get_temp(p);
5935f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
5945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_normalize_vec3( p, spot, spot_dir ); /* XXX: precompute! */
5955f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op2(p, VP_OPCODE_DP3, spot, 0, negate(VPpli), spot_dir);
5965f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op2(p, VP_OPCODE_SLT, slt, 0, swizzle1(spot_dir,W), spot);
5975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op2(p, VP_OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));
5985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op2(p, VP_OPCODE_MUL, att, 0, slt, spot);
5995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
6005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      release_temp(p, spot);
6015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      release_temp(p, slt);
6025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   }
6035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
6045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* Calculate distance attenuation:
6055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    */
6065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   if (light->ConstantAttenuation != 1.0 ||
6075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell       light->LinearAttenuation != 1.0 ||
6085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell       light->QuadraticAttenuation != 1.0) {
6095f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
6105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      /* 1/d,d,d,1/d */
6115f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op1(p, VP_OPCODE_RCP, dist, WRITEMASK_YZ, dist);
6125f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      /* 1,d,d*d,1/d */
6135f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op2(p, VP_OPCODE_MUL, dist, WRITEMASK_XZ, dist, swizzle1(dist,Y));
6145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      /* 1/dist-atten */
6155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op2(p, VP_OPCODE_DP3, dist, 0, attenuation, dist);
6165f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
6175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      if (light->SpotCutoff != 180.0F) {
6185f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 /* dist-atten */
6195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 emit_op1(p, VP_OPCODE_RCP, dist, 0, dist);
6205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 /* spot-atten * dist-atten */
6215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 emit_op2(p, VP_OPCODE_MUL, att, 0, dist, att);
6225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      } else {
6235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 /* dist-atten */
6245f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 emit_op1(p, VP_OPCODE_RCP, att, 0, dist);
6255f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      }
6265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   }
6275f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
6285f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   return att;
6295f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell}
6305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
6315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
632f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
633f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
634f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
635f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Need to add some addtional parameters to allow lighting in object
636f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye
637f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space lighting.
638f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
639f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_lighting( struct tnl_program *p )
640f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
641f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLcontext *ctx = p->ctx;
642f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   const GLboolean twoside = ctx->Light.Model.TwoSide;
643f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   const GLboolean separate = (ctx->Light.Model.ColorControl ==
644f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell			       GL_SEPARATE_SPECULAR_COLOR);
645f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint nr_lights = 0, count = 0;
646f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg normal = get_eye_normal(p);
647f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg lit = get_temp(p);
648f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg dots = get_temp(p);
649f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg _col0 = undef, _col1 = undef;
650f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg _bfc0 = undef, _bfc1 = undef;
651f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint i;
652f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
653f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   for (i = 0; i < MAX_LIGHTS; i++)
654f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      if (ctx->Light.Light[i].Enabled)
655f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 nr_lights++;
656f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
657f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   set_material_flags(p);
658f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
659f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   {
660f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg shininess = get_material(p, 0, STATE_SHININESS);
661f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      emit_op1(p, VP_OPCODE_MOV, dots,  WRITEMASK_W, swizzle1(shininess,X));
662f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      release_temp(p, shininess);
663f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
664f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      _col0 = make_temp(p, get_scenecolor(p, 0));
665f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      if (separate)
666f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 _col1 = make_temp(p, get_identity_param(p));
667f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      else
668f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 _col1 = _col0;
669f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
670f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
671f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
672f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (twoside) {
673f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg shininess = get_material(p, 1, STATE_SHININESS);
6745f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell      emit_op1(p, VP_OPCODE_MOV, dots, WRITEMASK_Z,
6755f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	       negate(swizzle1(shininess,X)));
676f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      release_temp(p, shininess);
677f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
678f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      _bfc0 = make_temp(p, get_scenecolor(p, 1));
679f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      if (separate)
680f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 _bfc1 = make_temp(p, get_identity_param(p));
681f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      else
682f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 _bfc1 = _bfc0;
683f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
684f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
685f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   for (i = 0; i < MAX_LIGHTS; i++) {
686f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct gl_light *light = &ctx->Light.Light[i];
687f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
688f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      if (light->Enabled) {
689f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 struct ureg half = undef;
690f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 struct ureg att = undef, VPpli = undef;
691f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
692f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 count++;
693f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
694f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 if (light->EyePosition[3] == 0) {
695f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    /* Can used precomputed constants in this case:
696f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	     */
6975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    VPpli = register_param3(p, STATE_LIGHT, i,
6985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				    STATE_POSITION_NORMALIZED);
699f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    half = register_param3(p, STATE_LIGHT, i, STATE_HALF);
700f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
7015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    /* Spot attenuation maybe applies to this case?  Could
7025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	     * precompute if so? */
703f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 }
704f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 else {
7055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    struct ureg Ppli = register_param3(p, STATE_LIGHT, i,
7065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell					       STATE_POSITION);
707f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg V = get_eye_position(p);
7085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    struct ureg dist = get_temp(p);
709f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
710f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    VPpli = get_temp(p);
711f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    half = get_temp(p);
712f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
713f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    /* Calulate VPpli vector
714f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	     */
715f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op2(p, VP_OPCODE_SUB, VPpli, 0, Ppli, V);
716f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
7175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    /* Normalize VPpli.  The dist value also used in
718f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	     * attenuation below.
719f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	     */
7205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    emit_op2(p, VP_OPCODE_DP3, dist, 0, VPpli, VPpli);
7215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    emit_op1(p, VP_OPCODE_RSQ, dist, 0, dist);
7225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    emit_op2(p, VP_OPCODE_MUL, VPpli, 0, VPpli, dist);
723f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
724f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
725f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    /* Calculate  attenuation:
726f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	     */
727f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (light->SpotCutoff != 180.0 ||
728f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		light->ConstantAttenuation != 1.0 ||
729f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		light->LinearAttenuation != 1.0 ||
730f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		light->QuadraticAttenuation != 1.0) {
7315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	       att = calculate_light_attenuation(p, i, light, VPpli, dist);
732f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
733f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
734f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
735f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    /* Calculate viewer direction, or use infinite viewer:
736f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	     */
737f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (ctx->Light.Model.LocalViewer) {
738f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       struct ureg eye_hat = get_eye_position_normalized(p);
739f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       emit_op2(p, VP_OPCODE_SUB, half, 0, VPpli, eye_hat);
740f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
741f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    else {
7425f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	       struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z);
743f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       emit_op2(p, VP_OPCODE_ADD, half, 0, VPpli, z_dir);
744f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
745f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
746f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_normalize_vec3(p, half, half);
747f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
7485f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    release_temp(p, dist);
749f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 }
750f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
751f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 /* Calculate dot products:
752f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	  */
753f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli);
754f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_DP3, dots, WRITEMASK_Y, normal, half);
755f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
756f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
757f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 /* Front face lighting:
758f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	  */
759f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 {
760f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT);
761f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE);
762f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR);
763f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg res0, res1;
764f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
765f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op1(p, VP_OPCODE_LIT, lit, 0, dots);
766f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
767f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (!is_undef(att))
768f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       emit_op2(p, VP_OPCODE_MUL, lit, 0, lit, att);
769f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
770f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
771f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (count == nr_lights) {
772f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       if (separate) {
773f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res0 = register_output( p, VERT_RESULT_COL0 );
774f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res1 = register_output( p, VERT_RESULT_COL1 );
775f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       }
776f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       else {
777f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res0 = _col0;
778f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res1 = register_output( p, VERT_RESULT_COL0 );
779f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       }
780f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    } else {
781f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       res0 = _col0;
782f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       res1 = _col1;
783f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
784f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
785f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op3(p, VP_OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0);
786f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op3(p, VP_OPCODE_MAD, res0, 0, swizzle1(lit,Y), diffuse, _col0);
787f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op3(p, VP_OPCODE_MAD, res1, 0, swizzle1(lit,Z), specular, _col1);
788f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
789f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    release_temp(p, ambient);
790f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    release_temp(p, diffuse);
791f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    release_temp(p, specular);
792f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 }
793f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
794f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 /* Back face lighting:
795f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	  */
796f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 if (twoside) {
797f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT);
798f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE);
799f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR);
800f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg res0, res1;
801f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
802f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op1(p, VP_OPCODE_LIT, lit, 0, negate(swizzle(dots,X,Y,W,Z)));
803f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
804f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (!is_undef(att))
805f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       emit_op2(p, VP_OPCODE_MUL, lit, 0, lit, att);
806f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
807f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (count == nr_lights) {
808f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       if (separate) {
809f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res0 = register_output( p, VERT_RESULT_BFC0 );
810f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res1 = register_output( p, VERT_RESULT_BFC1 );
811f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       }
812f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       else {
813f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res0 = _bfc0;
814f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  res1 = register_output( p, VERT_RESULT_BFC0 );
815f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       }
816f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    } else {
817f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       res0 = _bfc0;
818f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       res1 = _bfc1;
819f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
820f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
821f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
822f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op3(p, VP_OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0);
823f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op3(p, VP_OPCODE_MAD, res0, 0, swizzle1(lit,Y), diffuse, _bfc0);
824f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_op3(p, VP_OPCODE_MAD, res1, 0, swizzle1(lit,Z), specular, _bfc1);
825f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
826f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    release_temp(p, ambient);
827f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    release_temp(p, diffuse);
828f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    release_temp(p, specular);
829f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 }
830f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
831f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 release_temp(p, half);
832f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 release_temp(p, VPpli);
833f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 release_temp(p, att);
834f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      }
835f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
836f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
837f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   release_temps( p );
838f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
839f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
840f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
841f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_fog( struct tnl_program *p )
842f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
843f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLcontext *ctx = p->ctx;
844f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
845f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg fog = register_output(p, VERT_RESULT_FOGC);
846f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg input;
8475f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
848f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) {
849f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      input = swizzle1(get_eye_position(p), Z);
850f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
851f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   else {
852f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
853f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
854f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
855f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (tnl->_DoVertexFog) {
856f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg params = register_param1(p, STATE_FOG_PARAMS);
857f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg tmp = get_temp(p);
858f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
859f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      switch (ctx->Fog.Mode) {
860f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      case GL_LINEAR: {
861f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 struct ureg id = get_identity_param(p);
862f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_SUB, tmp, 0, swizzle1(params,Z), input);
863f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, swizzle1(params,W));
864f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */
8655f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 emit_op2(p, VP_OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W));
866f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 break;
867f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      }
868f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      case GL_EXP:
869f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op1(p, VP_OPCODE_ABS, tmp, 0, input);
870f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, swizzle1(params,X));
8715f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 emit_op2(p, VP_OPCODE_POW, fog, WRITEMASK_X,
8725f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell		  register_const1f(p, M_E), negate(tmp));
873f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 break;
874f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      case GL_EXP2:
875f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_MUL, tmp, 0, input, swizzle1(params,X));
876f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 emit_op2(p, VP_OPCODE_MUL, tmp, 0, tmp, tmp);
8775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	 emit_op2(p, VP_OPCODE_POW, fog, WRITEMASK_X,
8785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell		  register_const1f(p, M_E), negate(tmp));
879f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 break;
880f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      }
881f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
882f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      release_temp(p, tmp);
883f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
884f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   else {
885f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      /* results = incoming fog coords (compute fog per-fragment later)
886f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell       *
887f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell       * KW:  Is it really necessary to do anything in this case?
888f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell       */
889f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      emit_op1(p, VP_OPCODE_MOV, fog, WRITEMASK_X, input);
890f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
891f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
8925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
8935f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_reflect_texgen( struct tnl_program *p,
8945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				  struct ureg dest,
8955f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				  GLuint writemask )
8965f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{
8975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg normal = get_eye_normal(p);
8985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg eye_hat = get_eye_position_normalized(p);
8995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg tmp = get_temp(p);
900f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
9015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* n.u */
9025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, tmp, 0, normal, eye_hat);
9035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* 2n.u */
9045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_ADD, tmp, 0, tmp, tmp);
9055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* (-2n.u)n + u */
9065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op3(p, VP_OPCODE_MAD, dest, writemask, negate(tmp), normal, eye_hat);
9075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell}
9085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
9095f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_sphere_texgen( struct tnl_program *p,
9105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				 struct ureg dest,
9115f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				 GLuint writemask )
9125f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{
9135f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg normal = get_eye_normal(p);
9145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg eye_hat = get_eye_position_normalized(p);
9155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg tmp = get_temp(p);
9165f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg half = register_const1f(p, .5);
9175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg r = get_temp(p);
9185f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg inv_m = get_temp(p);
9195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg id = get_identity_param(p);
9205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
9215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* Could share the above calculations, but it would be
9225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    * a fairly odd state for someone to set (both sphere and
9235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    * reflection active for different texture coordinate
9245f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    * components.  Of course - if two texture units enable
9255f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    * reflect and/or sphere, things start to tilt in favour
9265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    * of seperating this out:
9275f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell    */
9285f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
9295f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* n.u */
9305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, tmp, 0, normal, eye_hat);
9315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* 2n.u */
9325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_ADD, tmp, 0, tmp, tmp);
9335f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* (-2n.u)n + u */
9345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op3(p, VP_OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat);
9355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* r + 0,0,1 */
9365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_ADD, tmp, 0, r, swizzle(id,X,Y,W,Z));
9375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* rx^2 + ry^2 + (rz+1)^2 */
9385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, tmp, 0, tmp, tmp);
9395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* 2/m */
9405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op1(p, VP_OPCODE_RSQ, tmp, 0, tmp);
9415f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* 1/m */
9425f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op2(p, VP_OPCODE_MUL, inv_m, 0, tmp, swizzle1(half,X));
9435f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* r/m + 1/2 */
9445f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   emit_op3(p, VP_OPCODE_MAD, dest, writemask, r, inv_m, swizzle1(half,X));
9455f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
9465f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   release_temp(p, tmp);
9475f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   release_temp(p, r);
9485f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   release_temp(p, inv_m);
9495f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell}
950f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
951f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
952f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_texture_transform( struct tnl_program *p )
953f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
954f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLcontext *ctx = p->ctx;
955f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   GLuint i, j;
956f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
957f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
958f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
959f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      GLuint texmat_enabled = ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i);
960f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      struct ureg out = register_output(p, VERT_RESULT_TEX0 + i);
961f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
962f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      if (texUnit->TexGenEnabled || texmat_enabled) {
963f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 struct ureg out_texgen = undef;
964f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
965f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 if (texUnit->TexGenEnabled) {
966f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    GLuint copy_mask = 0;
967f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    GLuint sphere_mask = 0;
968f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    GLuint reflect_mask = 0;
969f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    GLuint normal_mask = 0;
970f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    GLuint modes[4];
971f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
972f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (texmat_enabled)
973f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       out_texgen = get_temp(p);
974f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    else
975f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       out_texgen = out;
976f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
977f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    modes[0] = texUnit->GenModeS;
978f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    modes[1] = texUnit->GenModeT;
979f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    modes[2] = texUnit->GenModeR;
980f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    modes[3] = texUnit->GenModeQ;
981f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
982f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    for (j = 0; j < 4; j++) {
983f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       if (texUnit->TexGenEnabled & (1<<j)) {
984f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  switch (modes[j]) {
985f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  case GL_OBJECT_LINEAR: {
986f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     struct ureg obj = register_input(p, VERT_ATTRIB_POS);
9875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell		     struct ureg plane =
9885f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			register_param3(p, STATE_TEXGEN, i,
9895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell					STATE_TEXGEN_OBJECT_S + j);
9905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
9915f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell		     emit_op2(p, VP_OPCODE_DP4, out_texgen, WRITEMASK_X << j,
9925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			      obj, plane );
993f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     break;
994f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  }
995f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  case GL_EYE_LINEAR: {
996f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     struct ureg eye = get_eye_position(p);
9975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell		     struct ureg plane =
9985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			register_param3(p, STATE_TEXGEN, i,
9995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell					STATE_TEXGEN_EYE_S + j);
10005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell
10015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell		     emit_op2(p, VP_OPCODE_DP4, out_texgen, WRITEMASK_X << j,
10025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			      eye, plane );
1003f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     break;
1004f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  }
1005f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  case GL_SPHERE_MAP:
1006f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     sphere_mask |= WRITEMASK_X << j;
1007f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     break;
1008f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  case GL_REFLECTION_MAP_NV:
1009f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     reflect_mask |= WRITEMASK_X << j;
1010f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     break;
1011f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  case GL_NORMAL_MAP_NV:
1012f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     normal_mask |= WRITEMASK_X << j;
1013f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		     break;
1014f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  }
1015f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       }
1016f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       else
1017f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell		  copy_mask |= WRITEMASK_X << j;
1018f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
1019f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1020f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1021f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (sphere_mask) {
10225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	       build_sphere_texgen(p, out_texgen, sphere_mask);
1023f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
1024f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1025f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (reflect_mask) {
10265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	       build_reflect_texgen(p, out_texgen, reflect_mask);
1027f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
1028f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1029f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (normal_mask) {
1030f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       struct ureg normal = get_eye_normal(p);
1031f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       emit_op1(p, VP_OPCODE_MOV, out_texgen, normal_mask, normal );
1032f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
1033f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1034f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    if (copy_mask) {
1035f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i);
1036f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	       emit_op1(p, VP_OPCODE_MOV, out_texgen, copy_mask, in );
1037f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    }
1038f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 }
1039f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1040f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 if (texmat_enabled) {
1041f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    struct ureg texmat[4];
10425f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    struct ureg in = (!is_undef(out_texgen) ?
10435f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			      out_texgen :
10445f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell			      register_input(p, VERT_ATTRIB_TEX0+i));
10455f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell	    register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i,
10465f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell				    0, 3, 0, texmat );
1047f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	    emit_matrix_transform_vec4( p, out, texmat, in );
1048f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 }
1049f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1050f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell	 release_temps(p);
1051f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      }
1052f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
1053f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
1054f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1055f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1056f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Seems like it could be tighter:
1057f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */
1058f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_pointsize( struct tnl_program *p )
1059f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
1060f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg eye = get_eye_position(p);
10615f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg state_size = register_param1(p, STATE_POINT_SIZE);
10625f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION);
10635f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   struct ureg out = register_output(p, VERT_RESULT_PSIZ);
1064f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct ureg ut = get_temp(p);
1065f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1066f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* 1, -Z, Z * Z, 1 */
1067f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op1(p, VP_OPCODE_MOV, ut, 0, swizzle1(get_identity_param(p), W));
1068f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_MUL, ut, WRITEMASK_YZ, ut, negate(swizzle1(eye, Z)));
1069f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_MUL, ut, WRITEMASK_Z, ut, negate(swizzle1(eye, Z)));
1070f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1071f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
10725f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell   /* p1 +  p2 * dist + p3 * dist * dist, 0 */
1073f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_DP3, ut, 0, ut, state_attenuation);
1074f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1075f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* 1 / factor */
1076f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op1(p, VP_OPCODE_RCP, ut, 0, ut );
1077f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1078f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* out = pointSize / factor */
1079f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op2(p, VP_OPCODE_MUL, out, WRITEMASK_X, ut, state_size);
1080f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1081f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   release_temp(p, ut);
1082f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
1083f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1084f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1085f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1086f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellvoid _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
1087f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{
1088f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   struct tnl_program p;
1089f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1090f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (ctx->VertexProgram._Enabled)
1091f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      return;
1092f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1093f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   memset(&p, 0, sizeof(p));
1094f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.ctx = ctx;
1095f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program = &ctx->_TnlProgram;
1096f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1097f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.eye_position = undef;
1098f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.eye_position_normalized = undef;
1099f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.eye_normal = undef;
1100f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.identity = undef;
1101f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1102f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.temp_flag = 0;
1103f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.temp_reserved = ~((1<<MAX_NV_VERTEX_PROGRAM_TEMPS)-1);
1104f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1105f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (p.program->Instructions == NULL) {
1106f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      p.program->Instructions = MALLOC(sizeof(struct vp_instruction) * 100);
1107f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
1108f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1109f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* Initialize the arb_program struct */
1110f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->Base.String = 0;
1111f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->Base.NumInstructions =
1112f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->Base.NumTemporaries =
1113f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->Base.NumParameters =
1114f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0;
1115f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (p.program->Parameters)
1116f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      _mesa_free_parameter_list(p.program->Parameters);
1117f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->Parameters = _mesa_new_parameter_list ();
1118f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->InputsRead = 0;
1119f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   p.program->OutputsWritten = 0;
1120f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1121f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* Emit the program, starting with modelviewproject:
1122f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell    */
1123f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   build_hpos(&p);
1124f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1125f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* Lighting calculations:
1126f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell    */
1127f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (ctx->Light.Enabled)
1128f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      build_lighting(&p);
1129f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1130f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (ctx->Fog.Enabled)
1131f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      build_fog(&p);
1132f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1133f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (ctx->Texture._TexGenEnabled || ctx->Texture._TexMatEnabled)
1134f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      build_texture_transform(&p);
1135f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1136f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (ctx->Point._Attenuated)
1137f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      build_pointsize(&p);
1138f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1139f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1140f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* Finish up:
1141f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell    */
1142f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   emit_op1(&p, VP_OPCODE_END, undef, 0, undef);
1143f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell
1144f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   /* Disassemble:
1145f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell    */
1146f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   if (DISASSEM) {
1147f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell      _mesa_printf ("\n");
1148f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell   }
1149f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}
1150