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