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