state.c revision 01e04c3f
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"
5401e04c3fSmrg#include "vbo/vbo.h"
5501e04c3fSmrg#include "viewport.h"
56af69d88dSmrg#include "blend.h"
577117f1b4Smrg
587117f1b4Smrg
597117f1b4Smrg/**
6001e04c3fSmrg * Update the ctx->*Program._Current pointers to point to the
6101e04c3fSmrg * current/active programs.
623464ebd5Sriastradh *
633464ebd5Sriastradh * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
643464ebd5Sriastradh * programs or programs derived from fixed-function state.
65c1f859d4Smrg *
66c1f859d4Smrg * This function needs to be called after texture state validation in case
67c1f859d4Smrg * we're generating a fragment program from fixed-function texture state.
68c1f859d4Smrg *
69c1f859d4Smrg * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
70c1f859d4Smrg * or fragment program is being used.
71c1f859d4Smrg */
72c1f859d4Smrgstatic GLbitfield
733464ebd5Sriastradhupdate_program(struct gl_context *ctx)
74c1f859d4Smrg{
7501e04c3fSmrg   struct gl_program *vsProg =
76af69d88dSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
7701e04c3fSmrg   struct gl_program *tcsProg =
7801e04c3fSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
7901e04c3fSmrg   struct gl_program *tesProg =
8001e04c3fSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
8101e04c3fSmrg   struct gl_program *gsProg =
82af69d88dSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
8301e04c3fSmrg   struct gl_program *fsProg =
84af69d88dSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
8501e04c3fSmrg   struct gl_program *csProg =
8601e04c3fSmrg      ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
8701e04c3fSmrg   const struct gl_program *prevVP = ctx->VertexProgram._Current;
8801e04c3fSmrg   const struct gl_program *prevFP = ctx->FragmentProgram._Current;
8901e04c3fSmrg   const struct gl_program *prevGP = ctx->GeometryProgram._Current;
9001e04c3fSmrg   const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current;
9101e04c3fSmrg   const struct gl_program *prevTEP = ctx->TessEvalProgram._Current;
9201e04c3fSmrg   const struct gl_program *prevCP = ctx->ComputeProgram._Current;
937117f1b4Smrg
947117f1b4Smrg   /*
957117f1b4Smrg    * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
96c1f859d4Smrg    * pointers to the programs that should be used for rendering.  If either
97c1f859d4Smrg    * is NULL, use fixed-function code paths.
987117f1b4Smrg    *
997117f1b4Smrg    * These programs may come from several sources.  The priority is as
1007117f1b4Smrg    * follows:
1017117f1b4Smrg    *   1. OpenGL 2.0/ARB vertex/fragment shaders
1027117f1b4Smrg    *   2. ARB/NV vertex/fragment programs
10301e04c3fSmrg    *   3. ATI fragment shader
10401e04c3fSmrg    *   4. Programs derived from fixed-function state.
105c1f859d4Smrg    *
106c1f859d4Smrg    * Note: it's possible for a vertex shader to get used with a fragment
107c1f859d4Smrg    * program (and vice versa) here, but in practice that shouldn't ever
108c1f859d4Smrg    * come up, or matter.
1097117f1b4Smrg    */
1107117f1b4Smrg
11101e04c3fSmrg   if (fsProg) {
1123464ebd5Sriastradh      /* Use GLSL fragment shader */
11301e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg);
11401e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
11501e04c3fSmrg                              NULL);
116c1f859d4Smrg   }
11701e04c3fSmrg   else if (_mesa_arb_fragment_program_enabled(ctx)) {
1183464ebd5Sriastradh      /* Use user-defined fragment program */
11901e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
12001e04c3fSmrg                              ctx->FragmentProgram.Current);
12101e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
12201e04c3fSmrg			      NULL);
12301e04c3fSmrg   }
12401e04c3fSmrg   else if (_mesa_ati_fragment_shader_enabled(ctx) &&
12501e04c3fSmrg            ctx->ATIFragmentShader.Current->Program) {
12601e04c3fSmrg       /* Use the enabled ATI fragment shader's associated program */
12701e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
12801e04c3fSmrg                              ctx->ATIFragmentShader.Current->Program);
12901e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
13001e04c3fSmrg                              NULL);
131c1f859d4Smrg   }
132c1f859d4Smrg   else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
1333464ebd5Sriastradh      /* Use fragment program generated from fixed-function state */
134af69d88dSmrg      struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx);
135af69d88dSmrg
13601e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
13701e04c3fSmrg			      f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
13801e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
13901e04c3fSmrg			      f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
140c1f859d4Smrg   }
141c1f859d4Smrg   else {
1423464ebd5Sriastradh      /* No fragment program */
14301e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL);
14401e04c3fSmrg      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
14501e04c3fSmrg			      NULL);
146c1f859d4Smrg   }
1477117f1b4Smrg
14801e04c3fSmrg   if (gsProg) {
1493464ebd5Sriastradh      /* Use GLSL geometry shader */
15001e04c3fSmrg      _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg);
1513464ebd5Sriastradh   } else {
1523464ebd5Sriastradh      /* No geometry program */
15301e04c3fSmrg      _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL);
15401e04c3fSmrg   }
15501e04c3fSmrg
15601e04c3fSmrg   if (tesProg) {
15701e04c3fSmrg      /* Use GLSL tessellation evaluation shader */
15801e04c3fSmrg      _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg);
15901e04c3fSmrg   }
16001e04c3fSmrg   else {
16101e04c3fSmrg      /* No tessellation evaluation program */
16201e04c3fSmrg      _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL);
16301e04c3fSmrg   }
16401e04c3fSmrg
16501e04c3fSmrg   if (tcsProg) {
16601e04c3fSmrg      /* Use GLSL tessellation control shader */
16701e04c3fSmrg      _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg);
16801e04c3fSmrg   }
16901e04c3fSmrg   else {
17001e04c3fSmrg      /* No tessellation control program */
17101e04c3fSmrg      _mesa_reference_program(ctx, &ctx->TessCtrlProgram._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    */
17801e04c3fSmrg   if (vsProg) {
1793464ebd5Sriastradh      /* Use GLSL vertex shader */
18001e04c3fSmrg      assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode);
18101e04c3fSmrg      _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg);
182c1f859d4Smrg   }
18301e04c3fSmrg   else if (_mesa_arb_vertex_program_enabled(ctx)) {
1843464ebd5Sriastradh      /* Use user-defined vertex program */
18501e04c3fSmrg      assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode);
18601e04c3fSmrg      _mesa_reference_program(ctx, &ctx->VertexProgram._Current,
18701e04c3fSmrg                              ctx->VertexProgram.Current);
188c1f859d4Smrg   }
189c1f859d4Smrg   else if (ctx->VertexProgram._MaintainTnlProgram) {
1903464ebd5Sriastradh      /* Use vertex program generated from fixed-function state */
19101e04c3fSmrg      assert(VP_MODE_FF == ctx->VertexProgram._VPMode);
19201e04c3fSmrg      _mesa_reference_program(ctx, &ctx->VertexProgram._Current,
19301e04c3fSmrg                              _mesa_get_fixed_func_vertex_program(ctx));
19401e04c3fSmrg      _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram,
19501e04c3fSmrg                              ctx->VertexProgram._Current);
1967117f1b4Smrg   }
1977117f1b4Smrg   else {
198c1f859d4Smrg      /* no vertex program */
19901e04c3fSmrg      assert(VP_MODE_FF == ctx->VertexProgram._VPMode);
20001e04c3fSmrg      _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL);
20101e04c3fSmrg   }
20201e04c3fSmrg
20301e04c3fSmrg   if (csProg) {
20401e04c3fSmrg      /* Use GLSL compute shader */
20501e04c3fSmrg      _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg);
20601e04c3fSmrg   } else {
20701e04c3fSmrg      /* no compute program */
20801e04c3fSmrg      _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL);
209c1f859d4Smrg   }
2107117f1b4Smrg
211c1f859d4Smrg   /* Let the driver know what's happening:
212c1f859d4Smrg    */
21301e04c3fSmrg   if (ctx->FragmentProgram._Current != prevFP ||
21401e04c3fSmrg       ctx->VertexProgram._Current != prevVP ||
21501e04c3fSmrg       ctx->GeometryProgram._Current != prevGP ||
21601e04c3fSmrg       ctx->TessEvalProgram._Current != prevTEP ||
21701e04c3fSmrg       ctx->TessCtrlProgram._Current != prevTCP ||
21801e04c3fSmrg       ctx->ComputeProgram._Current != prevCP)
21901e04c3fSmrg      return _NEW_PROGRAM;
22001e04c3fSmrg
22101e04c3fSmrg   return 0;
22201e04c3fSmrg}
2233464ebd5Sriastradh
2243464ebd5Sriastradh
22501e04c3fSmrgstatic GLbitfield
22601e04c3fSmrgupdate_single_program_constants(struct gl_context *ctx,
22701e04c3fSmrg                                struct gl_program *prog,
22801e04c3fSmrg                                gl_shader_stage stage)
22901e04c3fSmrg{
23001e04c3fSmrg   if (prog) {
23101e04c3fSmrg      const struct gl_program_parameter_list *params = prog->Parameters;
23201e04c3fSmrg      if (params && params->StateFlags & ctx->NewState) {
23301e04c3fSmrg         if (ctx->DriverFlags.NewShaderConstants[stage])
23401e04c3fSmrg            ctx->NewDriverState |= ctx->DriverFlags.NewShaderConstants[stage];
23501e04c3fSmrg         else
23601e04c3fSmrg            return _NEW_PROGRAM_CONSTANTS;
2377117f1b4Smrg      }
2387117f1b4Smrg   }
23901e04c3fSmrg   return 0;
2407117f1b4Smrg}
2417117f1b4Smrg
2427117f1b4Smrg
2434a49301eSmrg/**
24401e04c3fSmrg * This updates fixed-func state constants such as gl_ModelViewMatrix.
2454a49301eSmrg * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0.
2464a49301eSmrg */
2474a49301eSmrgstatic GLbitfield
2483464ebd5Sriastradhupdate_program_constants(struct gl_context *ctx)
2494a49301eSmrg{
25001e04c3fSmrg   GLbitfield new_state =
25101e04c3fSmrg      update_single_program_constants(ctx, ctx->VertexProgram._Current,
25201e04c3fSmrg                                      MESA_SHADER_VERTEX) |
25301e04c3fSmrg      update_single_program_constants(ctx, ctx->FragmentProgram._Current,
25401e04c3fSmrg                                      MESA_SHADER_FRAGMENT);
25501e04c3fSmrg
25601e04c3fSmrg   if (ctx->API == API_OPENGL_COMPAT &&
25701e04c3fSmrg       ctx->Const.GLSLVersionCompat >= 150) {
25801e04c3fSmrg      new_state |=
25901e04c3fSmrg         update_single_program_constants(ctx, ctx->GeometryProgram._Current,
26001e04c3fSmrg                                         MESA_SHADER_GEOMETRY);
26101e04c3fSmrg
26201e04c3fSmrg      if (_mesa_has_ARB_tessellation_shader(ctx)) {
26301e04c3fSmrg         new_state |=
26401e04c3fSmrg            update_single_program_constants(ctx, ctx->TessCtrlProgram._Current,
26501e04c3fSmrg                                            MESA_SHADER_TESS_CTRL) |
26601e04c3fSmrg            update_single_program_constants(ctx, ctx->TessEvalProgram._Current,
26701e04c3fSmrg                                            MESA_SHADER_TESS_EVAL);
2684a49301eSmrg      }
2694a49301eSmrg   }
2704a49301eSmrg
2714a49301eSmrg   return new_state;
2724a49301eSmrg}
2734a49301eSmrg
2744a49301eSmrg
2757117f1b4Smrg/**
2767117f1b4Smrg * Compute derived GL state.
2773464ebd5Sriastradh * If __struct gl_contextRec::NewState is non-zero then this function \b must
2787117f1b4Smrg * be called before rendering anything.
2797117f1b4Smrg *
2807117f1b4Smrg * Calls dd_function_table::UpdateState to perform any internal state
2817117f1b4Smrg * management necessary.
2827117f1b4Smrg *
2837117f1b4Smrg * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
2847117f1b4Smrg * _mesa_update_buffer_bounds(),
2857117f1b4Smrg * _mesa_update_lighting() and _mesa_update_tnl_spaces().
2867117f1b4Smrg */
2877117f1b4Smrgvoid
2883464ebd5Sriastradh_mesa_update_state_locked( struct gl_context *ctx )
2897117f1b4Smrg{
2907117f1b4Smrg   GLbitfield new_state = ctx->NewState;
291c1f859d4Smrg   GLbitfield new_prog_state = 0x0;
29201e04c3fSmrg   const GLbitfield computed_states = ~(_NEW_CURRENT_ATTRIB | _NEW_LINE);
2937117f1b4Smrg
29401e04c3fSmrg   /* we can skip a bunch of state validation checks if the dirty
29501e04c3fSmrg    * state matches one or more bits in 'computed_states'.
29601e04c3fSmrg    */
29701e04c3fSmrg   if ((new_state & computed_states) == 0)
2984a49301eSmrg      goto out;
2994a49301eSmrg
3007117f1b4Smrg   if (MESA_VERBOSE & VERBOSE_STATE)
3017117f1b4Smrg      _mesa_print_state("_mesa_update_state", new_state);
3027117f1b4Smrg
3034a49301eSmrg   if (new_state & _NEW_BUFFERS)
30401e04c3fSmrg      _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
30501e04c3fSmrg
30601e04c3fSmrg   /* Handle Core and Compatibility contexts separately. */
30701e04c3fSmrg   if (ctx->API == API_OPENGL_COMPAT ||
30801e04c3fSmrg       ctx->API == API_OPENGLES) {
30901e04c3fSmrg      GLbitfield prog_flags = _NEW_PROGRAM;
31001e04c3fSmrg
31101e04c3fSmrg      /* Determine which state flags effect vertex/fragment program state */
31201e04c3fSmrg      if (ctx->FragmentProgram._MaintainTexEnvProgram) {
31301e04c3fSmrg         prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE_OBJECT | _NEW_FOG |
31401e04c3fSmrg                        _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT |
31501e04c3fSmrg                        _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP |
31601e04c3fSmrg                        _NEW_COLOR | _NEW_TEXTURE_STATE);
31701e04c3fSmrg      }
31801e04c3fSmrg      if (ctx->VertexProgram._MaintainTnlProgram) {
31901e04c3fSmrg         prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE_OBJECT |
32001e04c3fSmrg                        _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT |
32101e04c3fSmrg                        _NEW_FOG | _NEW_LIGHT | _NEW_TEXTURE_STATE |
32201e04c3fSmrg                        _MESA_NEW_NEED_EYE_COORDS);
32301e04c3fSmrg      }
3243464ebd5Sriastradh
32501e04c3fSmrg      /*
32601e04c3fSmrg       * Now update derived state info
32701e04c3fSmrg       */
32801e04c3fSmrg      if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
32901e04c3fSmrg         _mesa_update_modelview_project( ctx, new_state );
3307117f1b4Smrg
33101e04c3fSmrg      if (new_state & _NEW_TEXTURE_MATRIX)
33201e04c3fSmrg         _mesa_update_texture_matrices(ctx);
3337117f1b4Smrg
33401e04c3fSmrg      if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM))
33501e04c3fSmrg         _mesa_update_texture_state(ctx);
3367117f1b4Smrg
33701e04c3fSmrg      if (new_state & _NEW_LIGHT)
33801e04c3fSmrg         _mesa_update_lighting(ctx);
339c1f859d4Smrg
34001e04c3fSmrg      if (new_state & _NEW_PIXEL)
34101e04c3fSmrg         _mesa_update_pixel( ctx );
3427117f1b4Smrg
34301e04c3fSmrg      /* ctx->_NeedEyeCoords is now up to date.
34401e04c3fSmrg       *
34501e04c3fSmrg       * If the truth value of this variable has changed, update for the
34601e04c3fSmrg       * new lighting space and recompute the positions of lights and the
34701e04c3fSmrg       * normal transform.
34801e04c3fSmrg       *
34901e04c3fSmrg       * If the lighting space hasn't changed, may still need to recompute
35001e04c3fSmrg       * light positions & normal transforms for other reasons.
351c1f859d4Smrg       */
35201e04c3fSmrg      if (new_state & _MESA_NEW_NEED_EYE_COORDS)
35301e04c3fSmrg         _mesa_update_tnl_spaces( ctx, new_state );
35401e04c3fSmrg
35501e04c3fSmrg      if (new_state & prog_flags) {
35601e04c3fSmrg         /* When we generate programs from fixed-function vertex/fragment state
35701e04c3fSmrg          * this call may generate/bind a new program.  If so, we need to
35801e04c3fSmrg          * propogate the _NEW_PROGRAM flag to the driver.
35901e04c3fSmrg          */
36001e04c3fSmrg         new_prog_state |= update_program(ctx);
36101e04c3fSmrg      }
36201e04c3fSmrg   } else {
36301e04c3fSmrg      /* GL Core and GLES 2/3 contexts */
36401e04c3fSmrg      if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_PROGRAM))
36501e04c3fSmrg         _mesa_update_texture_state(ctx);
366af69d88dSmrg
36701e04c3fSmrg      if (new_state & _NEW_PROGRAM)
36801e04c3fSmrg         update_program(ctx);
369af69d88dSmrg   }
3704a49301eSmrg
3714a49301eSmrg out:
3724a49301eSmrg   new_prog_state |= update_program_constants(ctx);
3734a49301eSmrg
37401e04c3fSmrg   ctx->NewState |= new_prog_state;
37501e04c3fSmrg   vbo_exec_invalidate_state(ctx);
37601e04c3fSmrg
3777117f1b4Smrg   /*
3787117f1b4Smrg    * Give the driver a chance to act upon the new_state flags.
3797117f1b4Smrg    * The driver might plug in different span functions, for example.
3807117f1b4Smrg    * Also, this is where the driver can invalidate the state of any
3817117f1b4Smrg    * active modules (such as swrast_setup, swrast, tnl, etc).
3827117f1b4Smrg    */
38301e04c3fSmrg   ctx->Driver.UpdateState(ctx);
3847117f1b4Smrg   ctx->NewState = 0;
3857117f1b4Smrg}
3867117f1b4Smrg
3877117f1b4Smrg
3887117f1b4Smrg/* This is the usual entrypoint for state updates:
3897117f1b4Smrg */
3907117f1b4Smrgvoid
3913464ebd5Sriastradh_mesa_update_state( struct gl_context *ctx )
3927117f1b4Smrg{
3937117f1b4Smrg   _mesa_lock_context_textures(ctx);
3947117f1b4Smrg   _mesa_update_state_locked(ctx);
3957117f1b4Smrg   _mesa_unlock_context_textures(ctx);
3967117f1b4Smrg}
3974a49301eSmrg
3984a49301eSmrg
3994a49301eSmrg
4004a49301eSmrg
4014a49301eSmrg/**
4024a49301eSmrg * Want to figure out which fragment program inputs are actually
4034a49301eSmrg * constant/current values from ctx->Current.  These should be
4044a49301eSmrg * referenced as a tracked state variable rather than a fragment
4054a49301eSmrg * program input, to save the overhead of putting a constant value in
4064a49301eSmrg * every submitted vertex, transferring it to hardware, interpolating
4074a49301eSmrg * it across the triangle, etc...
4084a49301eSmrg *
4094a49301eSmrg * When there is a VP bound, just use vp->outputs.  But when we're
4104a49301eSmrg * generating vp from fixed function state, basically want to
4114a49301eSmrg * calculate:
4124a49301eSmrg *
4134a49301eSmrg * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) |
4144a49301eSmrg *                 potential_vp_outputs )
4154a49301eSmrg *
4164a49301eSmrg * Where potential_vp_outputs is calculated by looking at enabled
4174a49301eSmrg * texgen, etc.
4184a49301eSmrg *
4194a49301eSmrg * The generated fragment program should then only declare inputs that
4204a49301eSmrg * may vary or otherwise differ from the ctx->Current values.
4214a49301eSmrg * Otherwise, the fp should track them as state values instead.
4224a49301eSmrg */
4234a49301eSmrgvoid
4243464ebd5Sriastradh_mesa_set_varying_vp_inputs( struct gl_context *ctx,
42501e04c3fSmrg                             GLbitfield varying_inputs )
4264a49301eSmrg{
42701e04c3fSmrg   if (ctx->API != API_OPENGL_COMPAT &&
42801e04c3fSmrg       ctx->API != API_OPENGLES)
42901e04c3fSmrg      return;
43001e04c3fSmrg
4314a49301eSmrg   if (ctx->varying_vp_inputs != varying_inputs) {
4324a49301eSmrg      ctx->varying_vp_inputs = varying_inputs;
433af69d88dSmrg
434af69d88dSmrg      /* Only the fixed-func generated programs need to use the flag
435af69d88dSmrg       * and the fixed-func fragment program uses it only if there is also
436af69d88dSmrg       * a fixed-func vertex program, so this only depends on the latter.
437af69d88dSmrg       *
438af69d88dSmrg       * It's okay to check the VP pointer here, because this is called after
439af69d88dSmrg       * _mesa_update_state in the vbo module. */
440af69d88dSmrg      if (ctx->VertexProgram._TnlProgram ||
441af69d88dSmrg          ctx->FragmentProgram._TexEnvProgram) {
442af69d88dSmrg         ctx->NewState |= _NEW_VARYING_VP_INPUTS;
443af69d88dSmrg      }
44401e04c3fSmrg      /*printf("%s %x\n", __func__, varying_inputs);*/
4454a49301eSmrg   }
4464a49301eSmrg}
4474a49301eSmrg
4484a49301eSmrg
4494a49301eSmrg/**
4504a49301eSmrg * Used by drivers to tell core Mesa that the driver is going to
4514a49301eSmrg * install/ use its own vertex program.  In particular, this will
4524a49301eSmrg * prevent generated fragment programs from using state vars instead
4534a49301eSmrg * of ordinary varyings/inputs.
4544a49301eSmrg */
4554a49301eSmrgvoid
4563464ebd5Sriastradh_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag)
4574a49301eSmrg{
4584a49301eSmrg   if (ctx->VertexProgram._Overriden != flag) {
4594a49301eSmrg      ctx->VertexProgram._Overriden = flag;
4604a49301eSmrg
4614a49301eSmrg      /* Set one of the bits which will trigger fragment program
4624a49301eSmrg       * regeneration:
4634a49301eSmrg       */
4644a49301eSmrg      ctx->NewState |= _NEW_PROGRAM;
4654a49301eSmrg   }
4664a49301eSmrg}
46701e04c3fSmrg
46801e04c3fSmrg
46901e04c3fSmrgstatic void
47001e04c3fSmrgset_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m)
47101e04c3fSmrg{
47201e04c3fSmrg   if (ctx->VertexProgram._VPMode == m)
47301e04c3fSmrg      return;
47401e04c3fSmrg
47501e04c3fSmrg   /* On change we may get new maps into the current values */
47601e04c3fSmrg   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
47701e04c3fSmrg
47801e04c3fSmrg   /* Finally memorize the value */
47901e04c3fSmrg   ctx->VertexProgram._VPMode = m;
48001e04c3fSmrg}
48101e04c3fSmrg
48201e04c3fSmrg
48301e04c3fSmrg/**
48401e04c3fSmrg * Update ctx->VertexProgram._VPMode.
48501e04c3fSmrg * This is to distinguish whether we're running
48601e04c3fSmrg *   a vertex program/shader,
48701e04c3fSmrg *   a fixed-function TNL program or
48801e04c3fSmrg *   a fixed function vertex transformation without any program.
48901e04c3fSmrg */
49001e04c3fSmrgvoid
49101e04c3fSmrg_mesa_update_vertex_processing_mode(struct gl_context *ctx)
49201e04c3fSmrg{
49301e04c3fSmrg   if (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX])
49401e04c3fSmrg      set_vertex_processing_mode(ctx, VP_MODE_SHADER);
49501e04c3fSmrg   else if (_mesa_arb_vertex_program_enabled(ctx))
49601e04c3fSmrg      set_vertex_processing_mode(ctx, VP_MODE_SHADER);
49701e04c3fSmrg   else
49801e04c3fSmrg      set_vertex_processing_mode(ctx, VP_MODE_FF);
49901e04c3fSmrg}
50001e04c3fSmrg
50101e04c3fSmrg
50201e04c3fSmrg/**
50301e04c3fSmrg * Set the _DrawVAO and the net enabled arrays.
50401e04c3fSmrg * The vao->_Enabled bitmask is transformed due to position/generic0
50501e04c3fSmrg * as stored in vao->_AttributeMapMode. Then the filter bitmask is applied
50601e04c3fSmrg * to filter out arrays unwanted for the currently executed draw operation.
50701e04c3fSmrg * For example, the generic attributes are masked out form the _DrawVAO's
50801e04c3fSmrg * enabled arrays when a fixed function array draw is executed.
50901e04c3fSmrg */
51001e04c3fSmrgvoid
51101e04c3fSmrg_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao,
51201e04c3fSmrg                   GLbitfield filter)
51301e04c3fSmrg{
51401e04c3fSmrg   struct gl_vertex_array_object **ptr = &ctx->Array._DrawVAO;
51501e04c3fSmrg   bool new_array = false;
51601e04c3fSmrg   if (*ptr != vao) {
51701e04c3fSmrg      _mesa_reference_vao_(ctx, ptr, vao);
51801e04c3fSmrg
51901e04c3fSmrg      new_array = true;
52001e04c3fSmrg   }
52101e04c3fSmrg
52201e04c3fSmrg   if (vao->NewArrays) {
52301e04c3fSmrg      _mesa_update_vao_derived_arrays(ctx, vao);
52401e04c3fSmrg      vao->NewArrays = 0;
52501e04c3fSmrg
52601e04c3fSmrg      new_array = true;
52701e04c3fSmrg   }
52801e04c3fSmrg
52901e04c3fSmrg   /* May shuffle the position and generic0 bits around, filter out unwanted */
53001e04c3fSmrg   const GLbitfield enabled = filter & _mesa_get_vao_vp_inputs(vao);
53101e04c3fSmrg   if (ctx->Array._DrawVAOEnabledAttribs != enabled)
53201e04c3fSmrg      new_array = true;
53301e04c3fSmrg
53401e04c3fSmrg   if (new_array)
53501e04c3fSmrg      ctx->NewDriverState |= ctx->DriverFlags.NewArray;
53601e04c3fSmrg
53701e04c3fSmrg   ctx->Array._DrawVAOEnabledAttribs = enabled;
53801e04c3fSmrg   _mesa_set_varying_vp_inputs(ctx, enabled);
53901e04c3fSmrg}
540