state.c revision af69d88d
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg *
4c1f859d4Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
57117f1b4Smrg *
67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
87117f1b4Smrg * to deal in the Software without restriction, including without limitation
97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
117117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
127117f1b4Smrg *
137117f1b4Smrg * The above copyright notice and this permission notice shall be included
147117f1b4Smrg * in all copies or substantial portions of the Software.
157117f1b4Smrg *
167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg
267117f1b4Smrg/**
277117f1b4Smrg * \file state.c
287117f1b4Smrg * State management.
297117f1b4Smrg *
303464ebd5Sriastradh * This file manages recalculation of derived values in struct gl_context.
317117f1b4Smrg */
327117f1b4Smrg
33c1f859d4Smrg
347117f1b4Smrg#include "glheader.h"
35c1f859d4Smrg#include "mtypes.h"
36af69d88dSmrg#include "arrayobj.h"
377117f1b4Smrg#include "context.h"
38c1f859d4Smrg#include "debug.h"
39c1f859d4Smrg#include "macros.h"
40c1f859d4Smrg#include "ffvertex_prog.h"
417117f1b4Smrg#include "framebuffer.h"
427117f1b4Smrg#include "light.h"
437117f1b4Smrg#include "matrix.h"
447117f1b4Smrg#include "pixel.h"
453464ebd5Sriastradh#include "program/program.h"
463464ebd5Sriastradh#include "program/prog_parameter.h"
47af69d88dSmrg#include "shaderobj.h"
487117f1b4Smrg#include "state.h"
497117f1b4Smrg#include "stencil.h"
50c1f859d4Smrg#include "texenvprogram.h"
517117f1b4Smrg#include "texobj.h"
527117f1b4Smrg#include "texstate.h"
533464ebd5Sriastradh#include "varray.h"
54af69d88dSmrg#include "blend.h"
557117f1b4Smrg
567117f1b4Smrg
577117f1b4Smrg/**
58c1f859d4Smrg * Update the following fields:
59c1f859d4Smrg *   ctx->VertexProgram._Enabled
60c1f859d4Smrg *   ctx->FragmentProgram._Enabled
61c1f859d4Smrg *   ctx->ATIFragmentShader._Enabled
62c1f859d4Smrg * This needs to be done before texture state validation.
637117f1b4Smrg */
647117f1b4Smrgstatic void
653464ebd5Sriastradhupdate_program_enables(struct gl_context *ctx)
667117f1b4Smrg{
673464ebd5Sriastradh   /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment
683464ebd5Sriastradh    * program is enabled AND valid.  Similarly for ATI fragment shaders.
693464ebd5Sriastradh    * GLSL shaders not relevant here.
703464ebd5Sriastradh    */
717117f1b4Smrg   ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
727117f1b4Smrg      && ctx->VertexProgram.Current->Base.Instructions;
737117f1b4Smrg   ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
747117f1b4Smrg      && ctx->FragmentProgram.Current->Base.Instructions;
757117f1b4Smrg   ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
767117f1b4Smrg      && ctx->ATIFragmentShader.Current->Instructions[0];
77c1f859d4Smrg}
78c1f859d4Smrg
79c1f859d4Smrg
80c1f859d4Smrg/**
813464ebd5Sriastradh * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point
823464ebd5Sriastradh * to the current/active programs.  Then call ctx->Driver.BindProgram() to
833464ebd5Sriastradh * tell the driver which programs to use.
843464ebd5Sriastradh *
853464ebd5Sriastradh * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
863464ebd5Sriastradh * programs or programs derived from fixed-function state.
87c1f859d4Smrg *
88c1f859d4Smrg * This function needs to be called after texture state validation in case
89c1f859d4Smrg * we're generating a fragment program from fixed-function texture state.
90c1f859d4Smrg *
91c1f859d4Smrg * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
92c1f859d4Smrg * or fragment program is being used.
93c1f859d4Smrg */
94c1f859d4Smrgstatic GLbitfield
953464ebd5Sriastradhupdate_program(struct gl_context *ctx)
96c1f859d4Smrg{
97af69d88dSmrg   const struct gl_shader_program *vsProg =
98af69d88dSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
99af69d88dSmrg   const struct gl_shader_program *gsProg =
100af69d88dSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
101af69d88dSmrg   struct gl_shader_program *fsProg =
102af69d88dSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
103c1f859d4Smrg   const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
104c1f859d4Smrg   const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
1053464ebd5Sriastradh   const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
106c1f859d4Smrg   GLbitfield new_state = 0x0;
1077117f1b4Smrg
1087117f1b4Smrg   /*
1097117f1b4Smrg    * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
110c1f859d4Smrg    * pointers to the programs that should be used for rendering.  If either
111c1f859d4Smrg    * is NULL, use fixed-function code paths.
1127117f1b4Smrg    *
1137117f1b4Smrg    * These programs may come from several sources.  The priority is as
1147117f1b4Smrg    * follows:
1157117f1b4Smrg    *   1. OpenGL 2.0/ARB vertex/fragment shaders
1167117f1b4Smrg    *   2. ARB/NV vertex/fragment programs
1177117f1b4Smrg    *   3. Programs derived from fixed-function state.
118c1f859d4Smrg    *
119c1f859d4Smrg    * Note: it's possible for a vertex shader to get used with a fragment
120c1f859d4Smrg    * program (and vice versa) here, but in practice that shouldn't ever
121c1f859d4Smrg    * come up, or matter.
1227117f1b4Smrg    */
1237117f1b4Smrg
124af69d88dSmrg   if (fsProg && fsProg->LinkStatus
125af69d88dSmrg       && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
1263464ebd5Sriastradh      /* Use GLSL fragment shader */
127af69d88dSmrg      _mesa_reference_shader_program(ctx,
128af69d88dSmrg                                     &ctx->_Shader->_CurrentFragmentProgram,
129af69d88dSmrg				     fsProg);
130c1f859d4Smrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
131af69d88dSmrg                               gl_fragment_program(fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
132af69d88dSmrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
133af69d88dSmrg			       NULL);
134c1f859d4Smrg   }
135c1f859d4Smrg   else if (ctx->FragmentProgram._Enabled) {
1363464ebd5Sriastradh      /* Use user-defined fragment program */
137af69d88dSmrg      _mesa_reference_shader_program(ctx,
138af69d88dSmrg                                     &ctx->_Shader->_CurrentFragmentProgram,
139af69d88dSmrg				     NULL);
140c1f859d4Smrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
141c1f859d4Smrg                               ctx->FragmentProgram.Current);
142af69d88dSmrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
143af69d88dSmrg			       NULL);
144c1f859d4Smrg   }
145c1f859d4Smrg   else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
1463464ebd5Sriastradh      /* Use fragment program generated from fixed-function state */
147af69d88dSmrg      struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx);
148af69d88dSmrg
149af69d88dSmrg      _mesa_reference_shader_program(ctx,
150af69d88dSmrg                                     &ctx->_Shader->_CurrentFragmentProgram,
151af69d88dSmrg				     f);
152c1f859d4Smrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
153af69d88dSmrg			       gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
154c1f859d4Smrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
155af69d88dSmrg			       gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
156c1f859d4Smrg   }
157c1f859d4Smrg   else {
1583464ebd5Sriastradh      /* No fragment program */
159c1f859d4Smrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
160af69d88dSmrg      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
161af69d88dSmrg			       NULL);
162c1f859d4Smrg   }
1637117f1b4Smrg
164af69d88dSmrg   if (gsProg && gsProg->LinkStatus
165af69d88dSmrg       && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) {
1663464ebd5Sriastradh      /* Use GLSL geometry shader */
1673464ebd5Sriastradh      _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
168af69d88dSmrg			       gl_geometry_program(gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program));
1693464ebd5Sriastradh   } else {
1703464ebd5Sriastradh      /* No geometry program */
1713464ebd5Sriastradh      _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
1723464ebd5Sriastradh   }
1733464ebd5Sriastradh
174c1f859d4Smrg   /* Examine vertex program after fragment program as
175c1f859d4Smrg    * _mesa_get_fixed_func_vertex_program() needs to know active
176c1f859d4Smrg    * fragprog inputs.
177c1f859d4Smrg    */
178af69d88dSmrg   if (vsProg && vsProg->LinkStatus
179af69d88dSmrg       && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) {
1803464ebd5Sriastradh      /* Use GLSL vertex shader */
181c1f859d4Smrg      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
182af69d88dSmrg			       gl_vertex_program(vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program));
183c1f859d4Smrg   }
184c1f859d4Smrg   else if (ctx->VertexProgram._Enabled) {
1853464ebd5Sriastradh      /* Use user-defined vertex program */
186c1f859d4Smrg      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
187c1f859d4Smrg                               ctx->VertexProgram.Current);
188c1f859d4Smrg   }
189c1f859d4Smrg   else if (ctx->VertexProgram._MaintainTnlProgram) {
1903464ebd5Sriastradh      /* Use vertex program generated from fixed-function state */
191c1f859d4Smrg      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
192c1f859d4Smrg                               _mesa_get_fixed_func_vertex_program(ctx));
193c1f859d4Smrg      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
194c1f859d4Smrg                               ctx->VertexProgram._Current);
1957117f1b4Smrg   }
1967117f1b4Smrg   else {
197c1f859d4Smrg      /* no vertex program */
198c1f859d4Smrg      _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
199c1f859d4Smrg   }
2007117f1b4Smrg
201c1f859d4Smrg   /* Let the driver know what's happening:
202c1f859d4Smrg    */
203c1f859d4Smrg   if (ctx->FragmentProgram._Current != prevFP) {
204c1f859d4Smrg      new_state |= _NEW_PROGRAM;
205c1f859d4Smrg      if (ctx->Driver.BindProgram) {
206c1f859d4Smrg         ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
207c1f859d4Smrg                          (struct gl_program *) ctx->FragmentProgram._Current);
2087117f1b4Smrg      }
209c1f859d4Smrg   }
2103464ebd5Sriastradh
2113464ebd5Sriastradh   if (ctx->GeometryProgram._Current != prevGP) {
2123464ebd5Sriastradh      new_state |= _NEW_PROGRAM;
2133464ebd5Sriastradh      if (ctx->Driver.BindProgram) {
2143464ebd5Sriastradh         ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM,
2153464ebd5Sriastradh                            (struct gl_program *) ctx->GeometryProgram._Current);
2163464ebd5Sriastradh      }
2173464ebd5Sriastradh   }
2183464ebd5Sriastradh
219c1f859d4Smrg   if (ctx->VertexProgram._Current != prevVP) {
220c1f859d4Smrg      new_state |= _NEW_PROGRAM;
221c1f859d4Smrg      if (ctx->Driver.BindProgram) {
222c1f859d4Smrg         ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
223c1f859d4Smrg                            (struct gl_program *) ctx->VertexProgram._Current);
2247117f1b4Smrg      }
2257117f1b4Smrg   }
2267117f1b4Smrg
227c1f859d4Smrg   return new_state;
2287117f1b4Smrg}
2297117f1b4Smrg
2307117f1b4Smrg
2314a49301eSmrg/**
2324a49301eSmrg * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0.
2334a49301eSmrg */
2344a49301eSmrgstatic GLbitfield
2353464ebd5Sriastradhupdate_program_constants(struct gl_context *ctx)
2364a49301eSmrg{
2374a49301eSmrg   GLbitfield new_state = 0x0;
2384a49301eSmrg
2394a49301eSmrg   if (ctx->FragmentProgram._Current) {
2404a49301eSmrg      const struct gl_program_parameter_list *params =
2414a49301eSmrg         ctx->FragmentProgram._Current->Base.Parameters;
2424a49301eSmrg      if (params && params->StateFlags & ctx->NewState) {
2434a49301eSmrg         new_state |= _NEW_PROGRAM_CONSTANTS;
2444a49301eSmrg      }
2454a49301eSmrg   }
2464a49301eSmrg
2473464ebd5Sriastradh   if (ctx->GeometryProgram._Current) {
2483464ebd5Sriastradh      const struct gl_program_parameter_list *params =
2493464ebd5Sriastradh         ctx->GeometryProgram._Current->Base.Parameters;
2503464ebd5Sriastradh      /*FIXME: StateFlags is always 0 because we have unnamed constant
2513464ebd5Sriastradh       *       not state changes */
2523464ebd5Sriastradh      if (params /*&& params->StateFlags & ctx->NewState*/) {
2533464ebd5Sriastradh         new_state |= _NEW_PROGRAM_CONSTANTS;
2543464ebd5Sriastradh      }
2553464ebd5Sriastradh   }
2563464ebd5Sriastradh
2574a49301eSmrg   if (ctx->VertexProgram._Current) {
2584a49301eSmrg      const struct gl_program_parameter_list *params =
2594a49301eSmrg         ctx->VertexProgram._Current->Base.Parameters;
2604a49301eSmrg      if (params && params->StateFlags & ctx->NewState) {
2614a49301eSmrg         new_state |= _NEW_PROGRAM_CONSTANTS;
2624a49301eSmrg      }
2634a49301eSmrg   }
2644a49301eSmrg
2654a49301eSmrg   return new_state;
2664a49301eSmrg}
2674a49301eSmrg
2684a49301eSmrg
2694a49301eSmrg
2704a49301eSmrg
2717117f1b4Smrgstatic void
2723464ebd5Sriastradhupdate_viewport_matrix(struct gl_context *ctx)
2737117f1b4Smrg{
2747117f1b4Smrg   const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
275af69d88dSmrg   unsigned i;
2767117f1b4Smrg
2777117f1b4Smrg   ASSERT(depthMax > 0);
2787117f1b4Smrg
2797117f1b4Smrg   /* Compute scale and bias values. This is really driver-specific
2807117f1b4Smrg    * and should be maintained elsewhere if at all.
2817117f1b4Smrg    * NOTE: RasterPos uses this.
2827117f1b4Smrg    */
283af69d88dSmrg   for (i = 0; i < ctx->Const.MaxViewports; i++) {
284af69d88dSmrg      _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap,
285af69d88dSmrg                            ctx->ViewportArray[i].X, ctx->ViewportArray[i].Y,
286af69d88dSmrg                            ctx->ViewportArray[i].Width, ctx->ViewportArray[i].Height,
287af69d88dSmrg                            ctx->ViewportArray[i].Near, ctx->ViewportArray[i].Far,
288af69d88dSmrg                            depthMax);
289af69d88dSmrg   }
2907117f1b4Smrg}
2917117f1b4Smrg
2927117f1b4Smrg
293c1f859d4Smrg/**
294c1f859d4Smrg * Update derived multisample state.
295c1f859d4Smrg */
296c1f859d4Smrgstatic void
2973464ebd5Sriastradhupdate_multisample(struct gl_context *ctx)
298c1f859d4Smrg{
299c1f859d4Smrg   ctx->Multisample._Enabled = GL_FALSE;
300c1f859d4Smrg   if (ctx->Multisample.Enabled &&
301c1f859d4Smrg       ctx->DrawBuffer &&
302c1f859d4Smrg       ctx->DrawBuffer->Visual.sampleBuffers)
303c1f859d4Smrg      ctx->Multisample._Enabled = GL_TRUE;
304c1f859d4Smrg}
305c1f859d4Smrg
306c1f859d4Smrg
3077117f1b4Smrg/**
308af69d88dSmrg * Update the ctx->VertexProgram._TwoSideEnabled flag.
3097117f1b4Smrg */
3107117f1b4Smrgstatic void
311af69d88dSmrgupdate_twoside(struct gl_context *ctx)
3127117f1b4Smrg{
313af69d88dSmrg   if (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] ||
314af69d88dSmrg       ctx->VertexProgram._Enabled) {
315af69d88dSmrg      ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled;
316af69d88dSmrg   } else {
317af69d88dSmrg      ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled &&
318af69d88dSmrg					    ctx->Light.Model.TwoSide);
3197117f1b4Smrg   }
3207117f1b4Smrg}
3217117f1b4Smrg
3227117f1b4Smrg
3237117f1b4Smrg/**
3247117f1b4Smrg * Compute derived GL state.
3253464ebd5Sriastradh * If __struct gl_contextRec::NewState is non-zero then this function \b must
3267117f1b4Smrg * be called before rendering anything.
3277117f1b4Smrg *
3287117f1b4Smrg * Calls dd_function_table::UpdateState to perform any internal state
3297117f1b4Smrg * management necessary.
3307117f1b4Smrg *
3317117f1b4Smrg * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
3327117f1b4Smrg * _mesa_update_buffer_bounds(),
3337117f1b4Smrg * _mesa_update_lighting() and _mesa_update_tnl_spaces().
3347117f1b4Smrg */
3357117f1b4Smrgvoid
3363464ebd5Sriastradh_mesa_update_state_locked( struct gl_context *ctx )
3377117f1b4Smrg{
3387117f1b4Smrg   GLbitfield new_state = ctx->NewState;
339c1f859d4Smrg   GLbitfield prog_flags = _NEW_PROGRAM;
340c1f859d4Smrg   GLbitfield new_prog_state = 0x0;
3417117f1b4Smrg
3424a49301eSmrg   if (new_state == _NEW_CURRENT_ATTRIB)
3434a49301eSmrg      goto out;
3444a49301eSmrg
3457117f1b4Smrg   if (MESA_VERBOSE & VERBOSE_STATE)
3467117f1b4Smrg      _mesa_print_state("_mesa_update_state", new_state);
3477117f1b4Smrg
348c1f859d4Smrg   /* Determine which state flags effect vertex/fragment program state */
349c1f859d4Smrg   if (ctx->FragmentProgram._MaintainTexEnvProgram) {
3503464ebd5Sriastradh      prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG |
351af69d88dSmrg		     _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT |
352af69d88dSmrg		     _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP |
353af69d88dSmrg		     _NEW_COLOR);
354c1f859d4Smrg   }
355c1f859d4Smrg   if (ctx->VertexProgram._MaintainTnlProgram) {
356af69d88dSmrg      prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE |
357af69d88dSmrg                     _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT |
358c1f859d4Smrg                     _NEW_FOG | _NEW_LIGHT |
359c1f859d4Smrg                     _MESA_NEW_NEED_EYE_COORDS);
360c1f859d4Smrg   }
361c1f859d4Smrg
362c1f859d4Smrg   /*
363c1f859d4Smrg    * Now update derived state info
364c1f859d4Smrg    */
365c1f859d4Smrg
366c1f859d4Smrg   if (new_state & prog_flags)
367c1f859d4Smrg      update_program_enables( ctx );
3687117f1b4Smrg
3697117f1b4Smrg   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
3707117f1b4Smrg      _mesa_update_modelview_project( ctx, new_state );
3717117f1b4Smrg
3727117f1b4Smrg   if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
3737117f1b4Smrg      _mesa_update_texture( ctx, new_state );
3747117f1b4Smrg
3754a49301eSmrg   if (new_state & _NEW_BUFFERS)
3767117f1b4Smrg      _mesa_update_framebuffer(ctx);
3777117f1b4Smrg
3787117f1b4Smrg   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
3797117f1b4Smrg      _mesa_update_draw_buffer_bounds( ctx );
3807117f1b4Smrg
3817117f1b4Smrg   if (new_state & _NEW_LIGHT)
3827117f1b4Smrg      _mesa_update_lighting( ctx );
3837117f1b4Smrg
384af69d88dSmrg   if (new_state & (_NEW_LIGHT | _NEW_PROGRAM))
385af69d88dSmrg      update_twoside( ctx );
3863464ebd5Sriastradh
3874a49301eSmrg   if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
3887117f1b4Smrg      _mesa_update_stencil( ctx );
3897117f1b4Smrg
3903464ebd5Sriastradh   if (new_state & _NEW_PIXEL)
3917117f1b4Smrg      _mesa_update_pixel( ctx, new_state );
3927117f1b4Smrg
3937117f1b4Smrg   if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
3947117f1b4Smrg      update_viewport_matrix(ctx);
3957117f1b4Smrg
396af69d88dSmrg   if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS))
397c1f859d4Smrg      update_multisample( ctx );
398c1f859d4Smrg
3997117f1b4Smrg   /* ctx->_NeedEyeCoords is now up to date.
4007117f1b4Smrg    *
4017117f1b4Smrg    * If the truth value of this variable has changed, update for the
4027117f1b4Smrg    * new lighting space and recompute the positions of lights and the
4037117f1b4Smrg    * normal transform.
4047117f1b4Smrg    *
4057117f1b4Smrg    * If the lighting space hasn't changed, may still need to recompute
4067117f1b4Smrg    * light positions & normal transforms for other reasons.
4077117f1b4Smrg    */
4087117f1b4Smrg   if (new_state & _MESA_NEW_NEED_EYE_COORDS)
4097117f1b4Smrg      _mesa_update_tnl_spaces( ctx, new_state );
4107117f1b4Smrg
411c1f859d4Smrg   if (new_state & prog_flags) {
412c1f859d4Smrg      /* When we generate programs from fixed-function vertex/fragment state
413c1f859d4Smrg       * this call may generate/bind a new program.  If so, we need to
414c1f859d4Smrg       * propogate the _NEW_PROGRAM flag to the driver.
415c1f859d4Smrg       */
416c1f859d4Smrg      new_prog_state |= update_program( ctx );
417c1f859d4Smrg   }
418c1f859d4Smrg
419af69d88dSmrg   if (new_state & _NEW_ARRAY)
420af69d88dSmrg      _mesa_update_vao_client_arrays(ctx, ctx->Array.VAO);
421af69d88dSmrg
422af69d88dSmrg   if (ctx->Const.CheckArrayBounds &&
423af69d88dSmrg       new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) {
424af69d88dSmrg      _mesa_update_vao_max_element(ctx, ctx->Array.VAO);
425af69d88dSmrg   }
4264a49301eSmrg
4274a49301eSmrg out:
4284a49301eSmrg   new_prog_state |= update_program_constants(ctx);
4294a49301eSmrg
4307117f1b4Smrg   /*
4317117f1b4Smrg    * Give the driver a chance to act upon the new_state flags.
4327117f1b4Smrg    * The driver might plug in different span functions, for example.
4337117f1b4Smrg    * Also, this is where the driver can invalidate the state of any
4347117f1b4Smrg    * active modules (such as swrast_setup, swrast, tnl, etc).
4357117f1b4Smrg    *
4367117f1b4Smrg    * Set ctx->NewState to zero to avoid recursion if
4377117f1b4Smrg    * Driver.UpdateState() has to call FLUSH_VERTICES().  (fixed?)
4387117f1b4Smrg    */
439c1f859d4Smrg   new_state = ctx->NewState | new_prog_state;
4407117f1b4Smrg   ctx->NewState = 0;
4417117f1b4Smrg   ctx->Driver.UpdateState(ctx, new_state);
442af69d88dSmrg   ctx->Array.VAO->NewArrays = 0x0;
4437117f1b4Smrg}
4447117f1b4Smrg
4457117f1b4Smrg
4467117f1b4Smrg/* This is the usual entrypoint for state updates:
4477117f1b4Smrg */
4487117f1b4Smrgvoid
4493464ebd5Sriastradh_mesa_update_state( struct gl_context *ctx )
4507117f1b4Smrg{
4517117f1b4Smrg   _mesa_lock_context_textures(ctx);
4527117f1b4Smrg   _mesa_update_state_locked(ctx);
4537117f1b4Smrg   _mesa_unlock_context_textures(ctx);
4547117f1b4Smrg}
4554a49301eSmrg
4564a49301eSmrg
4574a49301eSmrg
4584a49301eSmrg
4594a49301eSmrg/**
4604a49301eSmrg * Want to figure out which fragment program inputs are actually
4614a49301eSmrg * constant/current values from ctx->Current.  These should be
4624a49301eSmrg * referenced as a tracked state variable rather than a fragment
4634a49301eSmrg * program input, to save the overhead of putting a constant value in
4644a49301eSmrg * every submitted vertex, transferring it to hardware, interpolating
4654a49301eSmrg * it across the triangle, etc...
4664a49301eSmrg *
4674a49301eSmrg * When there is a VP bound, just use vp->outputs.  But when we're
4684a49301eSmrg * generating vp from fixed function state, basically want to
4694a49301eSmrg * calculate:
4704a49301eSmrg *
4714a49301eSmrg * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) |
4724a49301eSmrg *                 potential_vp_outputs )
4734a49301eSmrg *
4744a49301eSmrg * Where potential_vp_outputs is calculated by looking at enabled
4754a49301eSmrg * texgen, etc.
4764a49301eSmrg *
4774a49301eSmrg * The generated fragment program should then only declare inputs that
4784a49301eSmrg * may vary or otherwise differ from the ctx->Current values.
4794a49301eSmrg * Otherwise, the fp should track them as state values instead.
4804a49301eSmrg */
4814a49301eSmrgvoid
4823464ebd5Sriastradh_mesa_set_varying_vp_inputs( struct gl_context *ctx,
483af69d88dSmrg                             GLbitfield64 varying_inputs )
4844a49301eSmrg{
4854a49301eSmrg   if (ctx->varying_vp_inputs != varying_inputs) {
4864a49301eSmrg      ctx->varying_vp_inputs = varying_inputs;
487af69d88dSmrg
488af69d88dSmrg      /* Only the fixed-func generated programs need to use the flag
489af69d88dSmrg       * and the fixed-func fragment program uses it only if there is also
490af69d88dSmrg       * a fixed-func vertex program, so this only depends on the latter.
491af69d88dSmrg       *
492af69d88dSmrg       * It's okay to check the VP pointer here, because this is called after
493af69d88dSmrg       * _mesa_update_state in the vbo module. */
494af69d88dSmrg      if (ctx->VertexProgram._TnlProgram ||
495af69d88dSmrg          ctx->FragmentProgram._TexEnvProgram) {
496af69d88dSmrg         ctx->NewState |= _NEW_VARYING_VP_INPUTS;
497af69d88dSmrg      }
498cdc920a0Smrg      /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/
4994a49301eSmrg   }
5004a49301eSmrg}
5014a49301eSmrg
5024a49301eSmrg
5034a49301eSmrg/**
5044a49301eSmrg * Used by drivers to tell core Mesa that the driver is going to
5054a49301eSmrg * install/ use its own vertex program.  In particular, this will
5064a49301eSmrg * prevent generated fragment programs from using state vars instead
5074a49301eSmrg * of ordinary varyings/inputs.
5084a49301eSmrg */
5094a49301eSmrgvoid
5103464ebd5Sriastradh_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag)
5114a49301eSmrg{
5124a49301eSmrg   if (ctx->VertexProgram._Overriden != flag) {
5134a49301eSmrg      ctx->VertexProgram._Overriden = flag;
5144a49301eSmrg
5154a49301eSmrg      /* Set one of the bits which will trigger fragment program
5164a49301eSmrg       * regeneration:
5174a49301eSmrg       */
5184a49301eSmrg      ctx->NewState |= _NEW_PROGRAM;
5194a49301eSmrg   }
5204a49301eSmrg}
521