Fixed MAXFIFO_S4. Removed WAIT_IDLE_EMPTY from savage_BCI_swap which resulted
[mesa.git] / src / mesa / tnl / t_vb_normals.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 5.1
5 *
6 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29
30 #include "glheader.h"
31 #include "colormac.h"
32 #include "context.h"
33 #include "macros.h"
34 #include "imports.h"
35 #include "mtypes.h"
36
37 #include "math/m_xform.h"
38
39 #include "t_context.h"
40 #include "t_pipeline.h"
41
42
43
44 struct normal_stage_data {
45 normal_func NormalTransform;
46 GLvector4f normal;
47 };
48
49 #define NORMAL_STAGE_DATA(stage) ((struct normal_stage_data *)stage->privatePtr)
50
51
52
53
54 static GLboolean run_normal_stage( GLcontext *ctx,
55 struct tnl_pipeline_stage *stage )
56 {
57 struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
58 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
59
60 ASSERT(store->NormalTransform);
61
62 if (stage->changed_inputs) {
63 /* We can only use the display list's saved normal lengths if we've
64 * got a transformation matrix with uniform scaling.
65 */
66 const GLfloat *lengths;
67 if (ctx->ModelviewMatrixStack.Top->flags & MAT_FLAG_GENERAL_SCALE)
68 lengths = NULL;
69 else
70 lengths = VB->NormalLengthPtr;
71
72 store->NormalTransform( ctx->ModelviewMatrixStack.Top,
73 ctx->_ModelViewInvScale,
74 VB->NormalPtr, /* input normals */
75 lengths,
76 &store->normal ); /* resulting normals */
77 }
78
79 VB->NormalPtr = &store->normal;
80 VB->AttribPtr[_TNL_ATTRIB_NORMAL] = VB->NormalPtr;
81
82 VB->NormalLengthPtr = 0; /* no longer valid */
83 return GL_TRUE;
84 }
85
86
87 static GLboolean run_validate_normal_stage( GLcontext *ctx,
88 struct tnl_pipeline_stage *stage )
89 {
90 struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
91
92
93 if (ctx->_NeedEyeCoords) {
94 GLuint transform = NORM_TRANSFORM_NO_ROT;
95
96 if (ctx->ModelviewMatrixStack.Top->flags & (MAT_FLAG_GENERAL |
97 MAT_FLAG_ROTATION |
98 MAT_FLAG_GENERAL_3D |
99 MAT_FLAG_PERSPECTIVE))
100 transform = NORM_TRANSFORM;
101
102
103 if (ctx->Transform.Normalize) {
104 store->NormalTransform = _mesa_normal_tab[transform | NORM_NORMALIZE];
105 }
106 else if (ctx->Transform.RescaleNormals &&
107 ctx->_ModelViewInvScale != 1.0) {
108 store->NormalTransform = _mesa_normal_tab[transform | NORM_RESCALE];
109 }
110 else {
111 store->NormalTransform = _mesa_normal_tab[transform];
112 }
113 }
114 else {
115 if (ctx->Transform.Normalize) {
116 store->NormalTransform = _mesa_normal_tab[NORM_NORMALIZE];
117 }
118 else if (!ctx->Transform.RescaleNormals &&
119 ctx->_ModelViewInvScale != 1.0) {
120 store->NormalTransform = _mesa_normal_tab[NORM_RESCALE];
121 }
122 else {
123 store->NormalTransform = 0;
124 }
125 }
126
127 if (store->NormalTransform) {
128 stage->run = run_normal_stage;
129 return stage->run( ctx, stage );
130 } else {
131 stage->active = GL_FALSE; /* !!! */
132 return GL_TRUE;
133 }
134 }
135
136
137 static void check_normal_transform( GLcontext *ctx,
138 struct tnl_pipeline_stage *stage )
139 {
140 stage->active = !ctx->VertexProgram.Enabled &&
141 (ctx->Light.Enabled || (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS));
142
143 /* Don't clobber the initialize function:
144 */
145 if (stage->privatePtr)
146 stage->run = run_validate_normal_stage;
147 }
148
149
150 static GLboolean alloc_normal_data( GLcontext *ctx,
151 struct tnl_pipeline_stage *stage )
152 {
153 TNLcontext *tnl = TNL_CONTEXT(ctx);
154 struct normal_stage_data *store;
155 stage->privatePtr = MALLOC(sizeof(*store));
156 store = NORMAL_STAGE_DATA(stage);
157 if (!store)
158 return GL_FALSE;
159
160 _mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 );
161
162 /* Now run the stage.
163 */
164 stage->run = run_validate_normal_stage;
165 return stage->run( ctx, stage );
166 }
167
168
169
170 static void free_normal_data( struct tnl_pipeline_stage *stage )
171 {
172 struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
173 if (store) {
174 _mesa_vector4f_free( &store->normal );
175 FREE( store );
176 stage->privatePtr = NULL;
177 }
178 }
179
180 #define _TNL_NEW_NORMAL_TRANSFORM (_NEW_MODELVIEW| \
181 _NEW_TRANSFORM| \
182 _NEW_PROGRAM| \
183 _MESA_NEW_NEED_NORMALS| \
184 _MESA_NEW_NEED_EYE_COORDS)
185
186
187
188 const struct tnl_pipeline_stage _tnl_normal_transform_stage =
189 {
190 "normal transform", /* name */
191 _TNL_NEW_NORMAL_TRANSFORM, /* re-check */
192 _TNL_NEW_NORMAL_TRANSFORM, /* re-run */
193 GL_FALSE, /* active? */
194 _TNL_BIT_NORMAL, /* inputs */
195 _TNL_BIT_NORMAL, /* outputs */
196 0, /* changed_inputs */
197 NULL, /* private data */
198 free_normal_data, /* destructor */
199 check_normal_transform, /* check */
200 alloc_normal_data /* run -- initially set to alloc */
201 };