Updates required for building the SciTech SNAP version of Mesa. This includes:
[mesa.git] / src / mesa / tnl / t_eval_api.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 - original code
27 * Brian Paul - vertex program updates
28 */
29
30
31 #include "glheader.h"
32 #include "colormac.h"
33 #include "context.h"
34 #include "macros.h"
35 #include "imports.h"
36 #include "mtypes.h"
37 #include "math/m_eval.h"
38
39 #include "t_eval_api.h"
40 #include "t_imm_api.h"
41 #include "t_imm_alloc.h"
42 #include "t_imm_exec.h"
43
44
45 /* KW: If are compiling, we don't know whether eval will produce a
46 * vertex when it is run in the future. If this is pure immediate
47 * mode, eval is a noop if neither vertex map is enabled.
48 *
49 * Thus we need to have a check in the display list code or
50 * elsewhere for eval(1,2) vertices in the case where
51 * map(1,2)_vertex is disabled, and to purge those vertices from
52 * the vb.
53 */
54 void
55 _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
56 {
57 GET_CURRENT_CONTEXT(ctx);
58 GLint i;
59 GLfloat u, du;
60 GLenum prim;
61 ASSERT_OUTSIDE_BEGIN_END(ctx);
62
63 if (MESA_VERBOSE & VERBOSE_API)
64 _mesa_debug(ctx, "glEvalMesh1()");
65
66 switch (mode) {
67 case GL_POINT:
68 prim = GL_POINTS;
69 break;
70 case GL_LINE:
71 prim = GL_LINE_STRIP;
72 break;
73 default:
74 _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
75 return;
76 }
77
78 /* No effect if vertex maps disabled.
79 */
80 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3 &&
81 (!ctx->VertexProgram.Enabled || !ctx->Eval.Map1Attrib[VERT_ATTRIB_POS]))
82 return;
83
84 du = ctx->Eval.MapGrid1du;
85 u = ctx->Eval.MapGrid1u1 + i1 * du;
86
87 /* Need to turn off compilation -- this is already saved, and the
88 * coordinates generated and the test above depend on state that
89 * may change before the list is executed.
90 *
91 * TODO: Anaylse display lists to determine if this state is
92 * constant.
93 *
94 * State to watch:
95 * - enabled maps
96 * - map state for each enabled map, including control points
97 * - grid state
98 *
99 * Could alternatively cache individual maps in arrays, rather than
100 * building immediates.
101 */
102 {
103 GLboolean compiling = ctx->CompileFlag;
104 TNLcontext *tnl = TNL_CONTEXT(ctx);
105 struct immediate *im = TNL_CURRENT_IM(ctx);
106 GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p);
107
108 NotifyBegin = tnl->Driver.NotifyBegin;
109 tnl->Driver.NotifyBegin = 0;
110
111 if (compiling) {
112 struct immediate *tmp = _tnl_alloc_immediate( ctx );
113 FLUSH_VERTICES( ctx, 0 );
114 SET_IMMEDIATE( ctx, tmp );
115 TNL_CURRENT_IM(ctx)->ref_count++;
116 ctx->CompileFlag = GL_FALSE;
117 }
118
119 _tnl_Begin( prim );
120 for (i=i1;i<=i2;i++,u+=du) {
121 _tnl_eval_coord1f( ctx, u );
122 }
123 _tnl_end_ctx(ctx);
124
125 /* Need this for replay *and* compile:
126 */
127 FLUSH_VERTICES( ctx, 0 );
128 tnl->Driver.NotifyBegin = NotifyBegin;
129
130 if (compiling) {
131 TNL_CURRENT_IM(ctx)->ref_count--;
132 ASSERT( TNL_CURRENT_IM(ctx)->ref_count == 0 );
133 _tnl_free_immediate( ctx, TNL_CURRENT_IM(ctx) );
134 SET_IMMEDIATE( ctx, im );
135 ctx->CompileFlag = GL_TRUE;
136 }
137 }
138 }
139
140
141
142 void
143 _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
144 {
145 GET_CURRENT_CONTEXT(ctx);
146 GLint i, j;
147 GLfloat u, du, v, dv, v1, u1;
148 ASSERT_OUTSIDE_BEGIN_END(ctx);
149
150 if (MESA_VERBOSE & VERBOSE_API)
151 _mesa_debug(ctx, "glEvalMesh2()");
152
153 /* No effect if vertex maps disabled.
154 */
155 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3 &&
156 (!ctx->VertexProgram.Enabled || !ctx->Eval.Map2Attrib[VERT_ATTRIB_POS]))
157 return;
158
159 du = ctx->Eval.MapGrid2du;
160 dv = ctx->Eval.MapGrid2dv;
161 v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
162 u1 = ctx->Eval.MapGrid2u1 + i1 * du;
163
164 /* Need to turn off compilation -- this is already saved, and the
165 * coordinates generated and the test above depend on state that
166 * may change before the list is executed.
167 */
168 {
169 GLboolean compiling = ctx->CompileFlag;
170 struct immediate *im = TNL_CURRENT_IM(ctx);
171 TNLcontext *tnl = TNL_CONTEXT(ctx);
172 GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p);
173
174 NotifyBegin = tnl->Driver.NotifyBegin;
175 tnl->Driver.NotifyBegin = 0;
176
177 if (compiling) {
178 struct immediate *tmp = _tnl_alloc_immediate( ctx );
179 FLUSH_VERTICES( ctx, 0 );
180 SET_IMMEDIATE( ctx, tmp );
181 TNL_CURRENT_IM(ctx)->ref_count++;
182 ctx->CompileFlag = GL_FALSE;
183 }
184
185 switch (mode) {
186 case GL_POINT:
187 _tnl_Begin( GL_POINTS );
188 for (v=v1,j=j1;j<=j2;j++,v+=dv) {
189 for (u=u1,i=i1;i<=i2;i++,u+=du) {
190 _tnl_eval_coord2f( ctx, u, v );
191 }
192 }
193 _tnl_end_ctx(ctx);
194 break;
195 case GL_LINE:
196 for (v=v1,j=j1;j<=j2;j++,v+=dv) {
197 _tnl_Begin( GL_LINE_STRIP );
198 for (u=u1,i=i1;i<=i2;i++,u+=du) {
199 _tnl_eval_coord2f( ctx, u, v );
200 }
201 _tnl_end_ctx(ctx);
202 }
203 for (u=u1,i=i1;i<=i2;i++,u+=du) {
204 _tnl_Begin( GL_LINE_STRIP );
205 for (v=v1,j=j1;j<=j2;j++,v+=dv) {
206 _tnl_eval_coord2f( ctx, u, v );
207 }
208 _tnl_end_ctx(ctx);
209 }
210 break;
211 case GL_FILL:
212 for (v=v1,j=j1;j<j2;j++,v+=dv) {
213 _tnl_Begin( GL_TRIANGLE_STRIP );
214 for (u=u1,i=i1;i<=i2;i++,u+=du) {
215 _tnl_eval_coord2f( ctx, u, v );
216 _tnl_eval_coord2f( ctx, u, v+dv );
217 }
218 _tnl_end_ctx(ctx);
219 }
220 break;
221 default:
222 _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
223 return;
224 }
225
226 /* Need this for replay *and* compile:
227 */
228 FLUSH_VERTICES( ctx, 0 );
229 tnl->Driver.NotifyBegin = NotifyBegin;
230
231 if (compiling) {
232 TNL_CURRENT_IM(ctx)->ref_count--;
233 _tnl_free_immediate( ctx, TNL_CURRENT_IM( ctx ) );
234 SET_IMMEDIATE( ctx, im );
235 ctx->CompileFlag = GL_TRUE;
236 }
237 }
238 }
239
240
241 void _tnl_eval_init( GLcontext *ctx )
242 {
243 GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
244 vfmt->EvalMesh1 = _tnl_exec_EvalMesh1;
245 vfmt->EvalMesh2 = _tnl_exec_EvalMesh2;
246 }