45d704182be351f27fb42f4be627aeec33406513
[reactos.git] / reactos / dll / opengl / mesa / src / mesa / main / state.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.3
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file state.c
28 * State management.
29 *
30 * This file manages recalculation of derived values in struct gl_context.
31 */
32
33
34 #include "glheader.h"
35 #include "mtypes.h"
36 #include "context.h"
37 #include "debug.h"
38 #include "macros.h"
39 #include "framebuffer.h"
40 #include "light.h"
41 #include "matrix.h"
42 #include "pixel.h"
43 #include "program/program.h"
44 #include "program/prog_parameter.h"
45 #include "shaderobj.h"
46 #include "state.h"
47 #include "stencil.h"
48 #include "texobj.h"
49 #include "texstate.h"
50 #include "varray.h"
51
52
53 static void
54 update_separate_specular(struct gl_context *ctx)
55 {
56 if (_mesa_need_secondary_color(ctx))
57 ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
58 else
59 ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR;
60 }
61
62
63 /**
64 * Helper for update_arrays().
65 * \return min(current min, array->_MaxElement).
66 */
67 static GLuint
68 update_min(GLuint min, struct gl_client_array *array)
69 {
70 _mesa_update_array_max_element(array);
71 return MIN2(min, array->_MaxElement);
72 }
73
74
75 /**
76 * Update ctx->Array._MaxElement (the max legal index into all enabled arrays).
77 * Need to do this upon new array state or new buffer object state.
78 */
79 static void
80 update_arrays( struct gl_context *ctx )
81 {
82 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
83 GLuint i, min = ~0;
84
85 /* find min of _MaxElement values for all enabled arrays.
86 * Note that the generic arrays always take precedence over
87 * the legacy arrays.
88 */
89
90 /* 0 */
91 if (ctx->VertexProgram._Current
92 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
93 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]);
94 }
95 else if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
96 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]);
97 }
98
99 /* 1 */
100 if (ctx->VertexProgram._Enabled
101 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1].Enabled) {
102 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1]);
103 }
104 /* no conventional vertex weight array */
105
106 /* 2 */
107 if (ctx->VertexProgram._Enabled
108 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2].Enabled) {
109 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2]);
110 }
111 else if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
112 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]);
113 }
114
115 /* 3 */
116 if (ctx->VertexProgram._Enabled
117 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3].Enabled) {
118 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3]);
119 }
120 else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
121 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]);
122 }
123
124 /* 4 */
125 if (ctx->VertexProgram._Enabled
126 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4].Enabled) {
127 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4]);
128 }
129 else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
130 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]);
131 }
132
133 /* 5 */
134 if (ctx->VertexProgram._Enabled
135 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5].Enabled) {
136 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5]);
137 }
138 else if (arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
139 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]);
140 }
141
142 /* 6 */
143 if (ctx->VertexProgram._Enabled
144 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6].Enabled) {
145 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6]);
146 }
147 else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
148 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]);
149 }
150
151 /* 7 */
152 if (ctx->VertexProgram._Enabled
153 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7].Enabled) {
154 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7]);
155 }
156
157 /* 8..15 */
158 for (i = 0; i < VERT_ATTRIB_TEX_MAX; i++) {
159 if (ctx->VertexProgram._Enabled
160 && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i].Enabled) {
161 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i]);
162 }
163 else if (i < ctx->Const.MaxTextureCoordUnits
164 && arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled) {
165 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]);
166 }
167 }
168
169 /* 16..31 */
170 if (ctx->VertexProgram._Current) {
171 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
172 if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) {
173 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
174 }
175 }
176 }
177
178 if (arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
179 min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]);
180 }
181
182 /* _MaxElement is one past the last legal array element */
183 arrayObj->_MaxElement = min;
184 }
185
186
187 /**
188 * Update the following fields:
189 * ctx->VertexProgram._Enabled
190 * ctx->FragmentProgram._Enabled
191 * ctx->ATIFragmentShader._Enabled
192 * This needs to be done before texture state validation.
193 */
194 static void
195 update_program_enables(struct gl_context *ctx)
196 {
197 /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment
198 * program is enabled AND valid. Similarly for ATI fragment shaders.
199 * GLSL shaders not relevant here.
200 */
201 ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
202 && ctx->VertexProgram.Current->Base.Instructions;
203 ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
204 && ctx->FragmentProgram.Current->Base.Instructions;
205 }
206
207
208 /**
209 * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point
210 * to the current/active programs. Then call ctx->Driver.BindProgram() to
211 * tell the driver which programs to use.
212 *
213 * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
214 * programs or programs derived from fixed-function state.
215 *
216 * This function needs to be called after texture state validation in case
217 * we're generating a fragment program from fixed-function texture state.
218 *
219 * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
220 * or fragment program is being used.
221 */
222 static GLbitfield
223 update_program(struct gl_context *ctx)
224 {
225 const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram;
226 struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram;
227 const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
228 const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
229 GLbitfield new_state = 0x0;
230
231 /*
232 * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
233 * pointers to the programs that should be used for rendering. If either
234 * is NULL, use fixed-function code paths.
235 *
236 * These programs may come from several sources. The priority is as
237 * follows:
238 * 1. OpenGL 2.0/ARB vertex/fragment shaders
239 * 2. ARB/NV vertex/fragment programs
240 * 3. Programs derived from fixed-function state.
241 *
242 * Note: it's possible for a vertex shader to get used with a fragment
243 * program (and vice versa) here, but in practice that shouldn't ever
244 * come up, or matter.
245 */
246
247 if (fsProg && fsProg->LinkStatus
248 && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
249 /* Use GLSL fragment shader */
250 _mesa_reference_shader_program(ctx,
251 &ctx->Shader._CurrentFragmentProgram,
252 fsProg);
253 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
254 (struct gl_fragment_program *)
255 fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
256 }
257 else if (ctx->FragmentProgram._Enabled) {
258 /* Use user-defined fragment program */
259 _mesa_reference_shader_program(ctx,
260 &ctx->Shader._CurrentFragmentProgram,
261 NULL);
262 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
263 ctx->FragmentProgram.Current);
264 }
265 else {
266 /* No fragment program */
267 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
268 }
269
270 /* Examine vertex program after fragment program as
271 * _mesa_get_fixed_func_vertex_program() needs to know active
272 * fragprog inputs.
273 */
274 if (vsProg && vsProg->LinkStatus
275 && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) {
276 /* Use GLSL vertex shader */
277 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
278 (struct gl_vertex_program *)
279 vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program);
280 }
281 else if (ctx->VertexProgram._Enabled) {
282 /* Use user-defined vertex program */
283 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
284 ctx->VertexProgram.Current);
285 }
286 else {
287 /* no vertex program */
288 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
289 }
290
291 /* Let the driver know what's happening:
292 */
293 if (ctx->FragmentProgram._Current != prevFP) {
294 new_state |= _NEW_PROGRAM;
295 if (ctx->Driver.BindProgram) {
296 ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
297 (struct gl_program *) ctx->FragmentProgram._Current);
298 }
299 }
300
301 if (ctx->VertexProgram._Current != prevVP) {
302 new_state |= _NEW_PROGRAM;
303 if (ctx->Driver.BindProgram) {
304 ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
305 (struct gl_program *) ctx->VertexProgram._Current);
306 }
307 }
308
309 return new_state;
310 }
311
312
313 /**
314 * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0.
315 */
316 static GLbitfield
317 update_program_constants(struct gl_context *ctx)
318 {
319 GLbitfield new_state = 0x0;
320
321 if (ctx->FragmentProgram._Current) {
322 const struct gl_program_parameter_list *params =
323 ctx->FragmentProgram._Current->Base.Parameters;
324 if (params && params->StateFlags & ctx->NewState) {
325 new_state |= _NEW_PROGRAM_CONSTANTS;
326 }
327 }
328
329 if (ctx->VertexProgram._Current) {
330 const struct gl_program_parameter_list *params =
331 ctx->VertexProgram._Current->Base.Parameters;
332 if (params && params->StateFlags & ctx->NewState) {
333 new_state |= _NEW_PROGRAM_CONSTANTS;
334 }
335 }
336
337 return new_state;
338 }
339
340
341
342
343 static void
344 update_viewport_matrix(struct gl_context *ctx)
345 {
346 const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
347
348 ASSERT(depthMax > 0);
349
350 /* Compute scale and bias values. This is really driver-specific
351 * and should be maintained elsewhere if at all.
352 * NOTE: RasterPos uses this.
353 */
354 _math_matrix_viewport(&ctx->Viewport._WindowMap,
355 ctx->Viewport.X, ctx->Viewport.Y,
356 ctx->Viewport.Width, ctx->Viewport.Height,
357 ctx->Viewport.Near, ctx->Viewport.Far,
358 depthMax);
359 }
360
361
362 /**
363 * Update the ctx->VertexProgram._TwoSideEnabled flag.
364 */
365 static void
366 update_twoside(struct gl_context *ctx)
367 {
368 if (ctx->Shader.CurrentVertexProgram ||
369 ctx->VertexProgram._Enabled) {
370 ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled;
371 } else {
372 ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled &&
373 ctx->Light.Model.TwoSide);
374 }
375 }
376
377
378 /*
379 * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET
380 * in ctx->_TriangleCaps if needed.
381 */
382 static void
383 update_polygon(struct gl_context *ctx)
384 {
385 ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET);
386
387 if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
388 ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
389
390 if ( ctx->Polygon.OffsetPoint
391 || ctx->Polygon.OffsetLine
392 || ctx->Polygon.OffsetFill)
393 ctx->_TriangleCaps |= DD_TRI_OFFSET;
394 }
395
396
397 /**
398 * Update the ctx->_TriangleCaps bitfield.
399 * XXX that bitfield should really go away someday!
400 * This function must be called after other update_*() functions since
401 * there are dependencies on some other derived values.
402 */
403 #if 0
404 static void
405 update_tricaps(struct gl_context *ctx, GLbitfield new_state)
406 {
407 ctx->_TriangleCaps = 0;
408
409 /*
410 * Points
411 */
412 if (1/*new_state & _NEW_POINT*/) {
413 if (ctx->Point.SmoothFlag)
414 ctx->_TriangleCaps |= DD_POINT_SMOOTH;
415 if (ctx->Point._Attenuated)
416 ctx->_TriangleCaps |= DD_POINT_ATTEN;
417 }
418
419 /*
420 * Lines
421 */
422 if (1/*new_state & _NEW_LINE*/) {
423 if (ctx->Line.SmoothFlag)
424 ctx->_TriangleCaps |= DD_LINE_SMOOTH;
425 if (ctx->Line.StippleFlag)
426 ctx->_TriangleCaps |= DD_LINE_STIPPLE;
427 }
428
429 /*
430 * Polygons
431 */
432 if (1/*new_state & _NEW_POLYGON*/) {
433 if (ctx->Polygon.SmoothFlag)
434 ctx->_TriangleCaps |= DD_TRI_SMOOTH;
435 if (ctx->Polygon.StippleFlag)
436 ctx->_TriangleCaps |= DD_TRI_STIPPLE;
437 if (ctx->Polygon.FrontMode != GL_FILL
438 || ctx->Polygon.BackMode != GL_FILL)
439 ctx->_TriangleCaps |= DD_TRI_UNFILLED;
440 if (ctx->Polygon.CullFlag
441 && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
442 ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
443 if (ctx->Polygon.OffsetPoint ||
444 ctx->Polygon.OffsetLine ||
445 ctx->Polygon.OffsetFill)
446 ctx->_TriangleCaps |= DD_TRI_OFFSET;
447 }
448
449 /*
450 * Lighting and shading
451 */
452 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
453 ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
454 if (ctx->Light.ShadeModel == GL_FLAT)
455 ctx->_TriangleCaps |= DD_FLATSHADE;
456 if (_mesa_need_secondary_color(ctx))
457 ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
458
459 /*
460 * Stencil
461 */
462 if (ctx->Stencil._TestTwoSide)
463 ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
464 }
465 #endif
466
467
468 /**
469 * Compute derived GL state.
470 * If __struct gl_contextRec::NewState is non-zero then this function \b must
471 * be called before rendering anything.
472 *
473 * Calls dd_function_table::UpdateState to perform any internal state
474 * management necessary.
475 *
476 * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
477 * _mesa_update_buffer_bounds(),
478 * _mesa_update_lighting() and _mesa_update_tnl_spaces().
479 */
480 void
481 _mesa_update_state_locked( struct gl_context *ctx )
482 {
483 GLbitfield new_state = ctx->NewState;
484 GLbitfield prog_flags = _NEW_PROGRAM;
485 GLbitfield new_prog_state = 0x0;
486
487 if (new_state == _NEW_CURRENT_ATTRIB)
488 goto out;
489
490 if (MESA_VERBOSE & VERBOSE_STATE)
491 _mesa_print_state("_mesa_update_state", new_state);
492
493 /*
494 * Now update derived state info
495 */
496
497 if (new_state & prog_flags)
498 update_program_enables( ctx );
499
500 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
501 _mesa_update_modelview_project( ctx, new_state );
502
503 if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
504 _mesa_update_texture( ctx, new_state );
505
506 if (new_state & _NEW_BUFFERS)
507 _mesa_update_framebuffer(ctx);
508
509 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
510 _mesa_update_draw_buffer_bounds( ctx );
511
512 if (new_state & _NEW_POLYGON)
513 update_polygon( ctx );
514
515 if (new_state & _NEW_LIGHT)
516 _mesa_update_lighting( ctx );
517
518 if (new_state & (_NEW_LIGHT | _NEW_PROGRAM))
519 update_twoside( ctx );
520
521 if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
522 _mesa_update_stencil( ctx );
523
524 if (new_state & _NEW_PIXEL)
525 _mesa_update_pixel( ctx, new_state );
526
527 if (new_state & _DD_NEW_SEPARATE_SPECULAR)
528 update_separate_specular( ctx );
529
530 if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
531 update_viewport_matrix(ctx);
532
533 #if 0
534 if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
535 | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
536 update_tricaps( ctx, new_state );
537 #endif
538
539 /* ctx->_NeedEyeCoords is now up to date.
540 *
541 * If the truth value of this variable has changed, update for the
542 * new lighting space and recompute the positions of lights and the
543 * normal transform.
544 *
545 * If the lighting space hasn't changed, may still need to recompute
546 * light positions & normal transforms for other reasons.
547 */
548 if (new_state & _MESA_NEW_NEED_EYE_COORDS)
549 _mesa_update_tnl_spaces( ctx, new_state );
550
551 if (new_state & prog_flags) {
552 /* When we generate programs from fixed-function vertex/fragment state
553 * this call may generate/bind a new program. If so, we need to
554 * propogate the _NEW_PROGRAM flag to the driver.
555 */
556 new_prog_state |= update_program( ctx );
557 }
558
559 if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT))
560 update_arrays( ctx );
561
562 out:
563 new_prog_state |= update_program_constants(ctx);
564
565 /*
566 * Give the driver a chance to act upon the new_state flags.
567 * The driver might plug in different span functions, for example.
568 * Also, this is where the driver can invalidate the state of any
569 * active modules (such as swrast_setup, swrast, tnl, etc).
570 *
571 * Set ctx->NewState to zero to avoid recursion if
572 * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?)
573 */
574 new_state = ctx->NewState | new_prog_state;
575 ctx->NewState = 0;
576 ctx->Driver.UpdateState(ctx, new_state);
577 ctx->Array.NewState = 0;
578 if (!ctx->Array.RebindArrays)
579 ctx->Array.RebindArrays = (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) != 0;
580 }
581
582
583 /* This is the usual entrypoint for state updates:
584 */
585 void
586 _mesa_update_state( struct gl_context *ctx )
587 {
588 _mesa_lock_context_textures(ctx);
589 _mesa_update_state_locked(ctx);
590 _mesa_unlock_context_textures(ctx);
591 }
592
593
594
595
596 /**
597 * Want to figure out which fragment program inputs are actually
598 * constant/current values from ctx->Current. These should be
599 * referenced as a tracked state variable rather than a fragment
600 * program input, to save the overhead of putting a constant value in
601 * every submitted vertex, transferring it to hardware, interpolating
602 * it across the triangle, etc...
603 *
604 * When there is a VP bound, just use vp->outputs. But when we're
605 * generating vp from fixed function state, basically want to
606 * calculate:
607 *
608 * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) |
609 * potential_vp_outputs )
610 *
611 * Where potential_vp_outputs is calculated by looking at enabled
612 * texgen, etc.
613 *
614 * The generated fragment program should then only declare inputs that
615 * may vary or otherwise differ from the ctx->Current values.
616 * Otherwise, the fp should track them as state values instead.
617 */
618 void
619 _mesa_set_varying_vp_inputs( struct gl_context *ctx,
620 GLbitfield64 varying_inputs )
621 {
622 if (ctx->varying_vp_inputs != varying_inputs) {
623 ctx->varying_vp_inputs = varying_inputs;
624 ctx->NewState |= _NEW_ARRAY;
625 /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/
626 }
627 }
628
629
630 /**
631 * Used by drivers to tell core Mesa that the driver is going to
632 * install/ use its own vertex program. In particular, this will
633 * prevent generated fragment programs from using state vars instead
634 * of ordinary varyings/inputs.
635 */
636 void
637 _mesa_set_vp_override(struct gl_context *ctx, GLboolean flag)
638 {
639 if (ctx->VertexProgram._Overriden != flag) {
640 ctx->VertexProgram._Overriden = flag;
641
642 /* Set one of the bits which will trigger fragment program
643 * regeneration:
644 */
645 ctx->NewState |= _NEW_PROGRAM;
646 }
647 }