1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci/** 27bf215546Sopenharmony_ci * \file state.c 28bf215546Sopenharmony_ci * State management. 29bf215546Sopenharmony_ci * 30bf215546Sopenharmony_ci * This file manages recalculation of derived values in struct gl_context. 31bf215546Sopenharmony_ci */ 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "glheader.h" 35bf215546Sopenharmony_ci#include "mtypes.h" 36bf215546Sopenharmony_ci#include "arrayobj.h" 37bf215546Sopenharmony_ci#include "context.h" 38bf215546Sopenharmony_ci#include "debug.h" 39bf215546Sopenharmony_ci#include "macros.h" 40bf215546Sopenharmony_ci#include "ffvertex_prog.h" 41bf215546Sopenharmony_ci#include "framebuffer.h" 42bf215546Sopenharmony_ci#include "light.h" 43bf215546Sopenharmony_ci#include "matrix.h" 44bf215546Sopenharmony_ci#include "pixel.h" 45bf215546Sopenharmony_ci#include "program/program.h" 46bf215546Sopenharmony_ci#include "program/prog_parameter.h" 47bf215546Sopenharmony_ci#include "shaderobj.h" 48bf215546Sopenharmony_ci#include "state.h" 49bf215546Sopenharmony_ci#include "stencil.h" 50bf215546Sopenharmony_ci#include "texenvprogram.h" 51bf215546Sopenharmony_ci#include "texobj.h" 52bf215546Sopenharmony_ci#include "texstate.h" 53bf215546Sopenharmony_ci#include "varray.h" 54bf215546Sopenharmony_ci#include "vbo/vbo.h" 55bf215546Sopenharmony_ci#include "viewport.h" 56bf215546Sopenharmony_ci#include "blend.h" 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci#include "state_tracker/st_context.h" 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_civoid 61bf215546Sopenharmony_ci_mesa_update_allow_draw_out_of_order(struct gl_context *ctx) 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci /* Out-of-order drawing is useful when vertex array draws and immediate 64bf215546Sopenharmony_ci * mode are interleaved. 65bf215546Sopenharmony_ci * 66bf215546Sopenharmony_ci * Example with 3 draws: 67bf215546Sopenharmony_ci * glBegin(); 68bf215546Sopenharmony_ci * glVertex(); 69bf215546Sopenharmony_ci * glEnd(); 70bf215546Sopenharmony_ci * glDrawElements(); 71bf215546Sopenharmony_ci * glBegin(); 72bf215546Sopenharmony_ci * glVertex(); 73bf215546Sopenharmony_ci * glEnd(); 74bf215546Sopenharmony_ci * 75bf215546Sopenharmony_ci * Out-of-order drawing changes the execution order like this: 76bf215546Sopenharmony_ci * glDrawElements(); 77bf215546Sopenharmony_ci * glBegin(); 78bf215546Sopenharmony_ci * glVertex(); 79bf215546Sopenharmony_ci * glVertex(); 80bf215546Sopenharmony_ci * glEnd(); 81bf215546Sopenharmony_ci * 82bf215546Sopenharmony_ci * If out-of-order draws are enabled, immediate mode vertices are not 83bf215546Sopenharmony_ci * flushed before glDrawElements, resulting in fewer draws and lower CPU 84bf215546Sopenharmony_ci * overhead. This helps workstation applications. 85bf215546Sopenharmony_ci * 86bf215546Sopenharmony_ci * This is a simplified version of out-of-order determination to catch 87bf215546Sopenharmony_ci * common cases. 88bf215546Sopenharmony_ci * 89bf215546Sopenharmony_ci * RadeonSI has a complete and more complicated out-of-order determination 90bf215546Sopenharmony_ci * for driver-internal reasons. 91bf215546Sopenharmony_ci */ 92bf215546Sopenharmony_ci /* Only the compatibility profile with immediate mode needs this. */ 93bf215546Sopenharmony_ci if (!ctx->Const.AllowDrawOutOfOrder) 94bf215546Sopenharmony_ci return; 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci assert(ctx->API == API_OPENGL_COMPAT); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci /* If all of these are NULL, GLSL is disabled. */ 99bf215546Sopenharmony_ci struct gl_program *vs = 100bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 101bf215546Sopenharmony_ci struct gl_program *tcs = 102bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 103bf215546Sopenharmony_ci struct gl_program *tes = 104bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 105bf215546Sopenharmony_ci struct gl_program *gs = 106bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 107bf215546Sopenharmony_ci struct gl_program *fs = 108bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 109bf215546Sopenharmony_ci GLenum16 depth_func = ctx->Depth.Func; 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci /* Z fighting and any primitives with equal Z shouldn't be reordered 112bf215546Sopenharmony_ci * with LESS/LEQUAL/GREATER/GEQUAL functions. 113bf215546Sopenharmony_ci * 114bf215546Sopenharmony_ci * When drawing 2 primitive with equal Z: 115bf215546Sopenharmony_ci * - with LEQUAL/GEQUAL, the last primitive wins the Z test. 116bf215546Sopenharmony_ci * - with LESS/GREATER, the first primitive wins the Z test. 117bf215546Sopenharmony_ci * 118bf215546Sopenharmony_ci * Here we ignore that on the basis that such cases don't occur in real 119bf215546Sopenharmony_ci * apps, and we they do occur, they occur with blending where out-of-order 120bf215546Sopenharmony_ci * drawing is always disabled. 121bf215546Sopenharmony_ci */ 122bf215546Sopenharmony_ci bool previous_state = ctx->_AllowDrawOutOfOrder; 123bf215546Sopenharmony_ci ctx->_AllowDrawOutOfOrder = 124bf215546Sopenharmony_ci ctx->DrawBuffer && 125bf215546Sopenharmony_ci ctx->DrawBuffer->Visual.depthBits && 126bf215546Sopenharmony_ci ctx->Depth.Test && 127bf215546Sopenharmony_ci ctx->Depth.Mask && 128bf215546Sopenharmony_ci (depth_func == GL_NEVER || 129bf215546Sopenharmony_ci depth_func == GL_LESS || 130bf215546Sopenharmony_ci depth_func == GL_LEQUAL || 131bf215546Sopenharmony_ci depth_func == GL_GREATER || 132bf215546Sopenharmony_ci depth_func == GL_GEQUAL) && 133bf215546Sopenharmony_ci (!ctx->DrawBuffer->Visual.stencilBits || 134bf215546Sopenharmony_ci !ctx->Stencil.Enabled) && 135bf215546Sopenharmony_ci (!ctx->Color.ColorMask || 136bf215546Sopenharmony_ci (!ctx->Color.BlendEnabled && 137bf215546Sopenharmony_ci (!ctx->Color.ColorLogicOpEnabled || 138bf215546Sopenharmony_ci ctx->Color._LogicOp == COLOR_LOGICOP_COPY))) && 139bf215546Sopenharmony_ci (!vs || !vs->info.writes_memory) && 140bf215546Sopenharmony_ci (!tes || !tes->info.writes_memory) && 141bf215546Sopenharmony_ci (!tcs || !tcs->info.writes_memory) && 142bf215546Sopenharmony_ci (!gs || !gs->info.writes_memory) && 143bf215546Sopenharmony_ci (!fs || !fs->info.writes_memory || !fs->info.fs.early_fragment_tests); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci /* If we are disabling out-of-order drawing, we need to flush queued 146bf215546Sopenharmony_ci * vertices. 147bf215546Sopenharmony_ci */ 148bf215546Sopenharmony_ci if (previous_state && !ctx->_AllowDrawOutOfOrder) 149bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci/** 154bf215546Sopenharmony_ci * Update the ctx->*Program._Current pointers to point to the 155bf215546Sopenharmony_ci * current/active programs. 156bf215546Sopenharmony_ci * 157bf215546Sopenharmony_ci * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment 158bf215546Sopenharmony_ci * programs or programs derived from fixed-function state. 159bf215546Sopenharmony_ci * 160bf215546Sopenharmony_ci * This function needs to be called after texture state validation in case 161bf215546Sopenharmony_ci * we're generating a fragment program from fixed-function texture state. 162bf215546Sopenharmony_ci * 163bf215546Sopenharmony_ci * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex 164bf215546Sopenharmony_ci * or fragment program is being used. 165bf215546Sopenharmony_ci */ 166bf215546Sopenharmony_cistatic GLbitfield 167bf215546Sopenharmony_ciupdate_program(struct gl_context *ctx) 168bf215546Sopenharmony_ci{ 169bf215546Sopenharmony_ci struct gl_program *vsProg = 170bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 171bf215546Sopenharmony_ci struct gl_program *tcsProg = 172bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 173bf215546Sopenharmony_ci struct gl_program *tesProg = 174bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 175bf215546Sopenharmony_ci struct gl_program *gsProg = 176bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 177bf215546Sopenharmony_ci struct gl_program *fsProg = 178bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 179bf215546Sopenharmony_ci struct gl_program *csProg = 180bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 181bf215546Sopenharmony_ci const struct gl_program *prevVP = ctx->VertexProgram._Current; 182bf215546Sopenharmony_ci const struct gl_program *prevFP = ctx->FragmentProgram._Current; 183bf215546Sopenharmony_ci const struct gl_program *prevGP = ctx->GeometryProgram._Current; 184bf215546Sopenharmony_ci const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current; 185bf215546Sopenharmony_ci const struct gl_program *prevTEP = ctx->TessEvalProgram._Current; 186bf215546Sopenharmony_ci const struct gl_program *prevCP = ctx->ComputeProgram._Current; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci /* 189bf215546Sopenharmony_ci * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current 190bf215546Sopenharmony_ci * pointers to the programs that should be used for rendering. If either 191bf215546Sopenharmony_ci * is NULL, use fixed-function code paths. 192bf215546Sopenharmony_ci * 193bf215546Sopenharmony_ci * These programs may come from several sources. The priority is as 194bf215546Sopenharmony_ci * follows: 195bf215546Sopenharmony_ci * 1. OpenGL 2.0/ARB vertex/fragment shaders 196bf215546Sopenharmony_ci * 2. ARB/NV vertex/fragment programs 197bf215546Sopenharmony_ci * 3. ATI fragment shader 198bf215546Sopenharmony_ci * 4. Programs derived from fixed-function state. 199bf215546Sopenharmony_ci * 200bf215546Sopenharmony_ci * Note: it's possible for a vertex shader to get used with a fragment 201bf215546Sopenharmony_ci * program (and vice versa) here, but in practice that shouldn't ever 202bf215546Sopenharmony_ci * come up, or matter. 203bf215546Sopenharmony_ci */ 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci if (fsProg) { 206bf215546Sopenharmony_ci /* Use GLSL fragment shader */ 207bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg); 208bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 209bf215546Sopenharmony_ci NULL); 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci else if (_mesa_arb_fragment_program_enabled(ctx)) { 212bf215546Sopenharmony_ci /* Use user-defined fragment program */ 213bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 214bf215546Sopenharmony_ci ctx->FragmentProgram.Current); 215bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 216bf215546Sopenharmony_ci NULL); 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci else if (_mesa_ati_fragment_shader_enabled(ctx) && 219bf215546Sopenharmony_ci ctx->ATIFragmentShader.Current->Program) { 220bf215546Sopenharmony_ci /* Use the enabled ATI fragment shader's associated program */ 221bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 222bf215546Sopenharmony_ci ctx->ATIFragmentShader.Current->Program); 223bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 224bf215546Sopenharmony_ci NULL); 225bf215546Sopenharmony_ci } 226bf215546Sopenharmony_ci else { 227bf215546Sopenharmony_ci /* Use fragment program generated from fixed-function state */ 228bf215546Sopenharmony_ci struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, 231bf215546Sopenharmony_ci f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 232bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, 233bf215546Sopenharmony_ci f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); 234bf215546Sopenharmony_ci } 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci if (gsProg) { 237bf215546Sopenharmony_ci /* Use GLSL geometry shader */ 238bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg); 239bf215546Sopenharmony_ci } else { 240bf215546Sopenharmony_ci /* No geometry program */ 241bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL); 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci if (tesProg) { 245bf215546Sopenharmony_ci /* Use GLSL tessellation evaluation shader */ 246bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg); 247bf215546Sopenharmony_ci } 248bf215546Sopenharmony_ci else { 249bf215546Sopenharmony_ci /* No tessellation evaluation program */ 250bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL); 251bf215546Sopenharmony_ci } 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci if (tcsProg) { 254bf215546Sopenharmony_ci /* Use GLSL tessellation control shader */ 255bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg); 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci else { 258bf215546Sopenharmony_ci /* No tessellation control program */ 259bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL); 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci /* Examine vertex program after fragment program as 263bf215546Sopenharmony_ci * _mesa_get_fixed_func_vertex_program() needs to know active 264bf215546Sopenharmony_ci * fragprog inputs. 265bf215546Sopenharmony_ci */ 266bf215546Sopenharmony_ci if (vsProg) { 267bf215546Sopenharmony_ci /* Use GLSL vertex shader */ 268bf215546Sopenharmony_ci assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); 269bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg); 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci else if (_mesa_arb_vertex_program_enabled(ctx)) { 272bf215546Sopenharmony_ci /* Use user-defined vertex program */ 273bf215546Sopenharmony_ci assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); 274bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->VertexProgram._Current, 275bf215546Sopenharmony_ci ctx->VertexProgram.Current); 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci else { 278bf215546Sopenharmony_ci /* Use vertex program generated from fixed-function state */ 279bf215546Sopenharmony_ci assert(VP_MODE_FF == ctx->VertexProgram._VPMode); 280bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->VertexProgram._Current, 281bf215546Sopenharmony_ci _mesa_get_fixed_func_vertex_program(ctx)); 282bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, 283bf215546Sopenharmony_ci ctx->VertexProgram._Current); 284bf215546Sopenharmony_ci } 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci if (csProg) { 287bf215546Sopenharmony_ci /* Use GLSL compute shader */ 288bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg); 289bf215546Sopenharmony_ci } else { 290bf215546Sopenharmony_ci /* no compute program */ 291bf215546Sopenharmony_ci _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL); 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci bool vp_changed = ctx->VertexProgram._Current != prevVP; 295bf215546Sopenharmony_ci bool tep_changed = ctx->TessEvalProgram._Current != prevTEP; 296bf215546Sopenharmony_ci bool gp_changed = ctx->GeometryProgram._Current != prevGP; 297bf215546Sopenharmony_ci if (ctx->GeometryProgram._Current) { 298bf215546Sopenharmony_ci ctx->LastVertexStageDirty |= gp_changed; 299bf215546Sopenharmony_ci } else if (ctx->TessEvalProgram._Current) { 300bf215546Sopenharmony_ci ctx->LastVertexStageDirty |= gp_changed | tep_changed; 301bf215546Sopenharmony_ci } else { 302bf215546Sopenharmony_ci ctx->LastVertexStageDirty |= gp_changed | tep_changed | vp_changed; 303bf215546Sopenharmony_ci } 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci /* Let the driver know what's happening: 306bf215546Sopenharmony_ci */ 307bf215546Sopenharmony_ci if (ctx->FragmentProgram._Current != prevFP || 308bf215546Sopenharmony_ci ctx->VertexProgram._Current != prevVP || 309bf215546Sopenharmony_ci ctx->GeometryProgram._Current != prevGP || 310bf215546Sopenharmony_ci ctx->TessEvalProgram._Current != prevTEP || 311bf215546Sopenharmony_ci ctx->TessCtrlProgram._Current != prevTCP || 312bf215546Sopenharmony_ci ctx->ComputeProgram._Current != prevCP) 313bf215546Sopenharmony_ci return _NEW_PROGRAM; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci return 0; 316bf215546Sopenharmony_ci} 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_cistatic GLbitfield 320bf215546Sopenharmony_ciupdate_single_program_constants(struct gl_context *ctx, 321bf215546Sopenharmony_ci struct gl_program *prog, 322bf215546Sopenharmony_ci gl_shader_stage stage) 323bf215546Sopenharmony_ci{ 324bf215546Sopenharmony_ci if (prog) { 325bf215546Sopenharmony_ci const struct gl_program_parameter_list *params = prog->Parameters; 326bf215546Sopenharmony_ci if (params && params->StateFlags & ctx->NewState) { 327bf215546Sopenharmony_ci if (ctx->DriverFlags.NewShaderConstants[stage]) 328bf215546Sopenharmony_ci ctx->NewDriverState |= ctx->DriverFlags.NewShaderConstants[stage]; 329bf215546Sopenharmony_ci else 330bf215546Sopenharmony_ci return _NEW_PROGRAM_CONSTANTS; 331bf215546Sopenharmony_ci } 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci return 0; 334bf215546Sopenharmony_ci} 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci/** 338bf215546Sopenharmony_ci * This updates fixed-func state constants such as gl_ModelViewMatrix. 339bf215546Sopenharmony_ci * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0. 340bf215546Sopenharmony_ci */ 341bf215546Sopenharmony_cistatic GLbitfield 342bf215546Sopenharmony_ciupdate_program_constants(struct gl_context *ctx) 343bf215546Sopenharmony_ci{ 344bf215546Sopenharmony_ci GLbitfield new_state = 345bf215546Sopenharmony_ci update_single_program_constants(ctx, ctx->VertexProgram._Current, 346bf215546Sopenharmony_ci MESA_SHADER_VERTEX) | 347bf215546Sopenharmony_ci update_single_program_constants(ctx, ctx->FragmentProgram._Current, 348bf215546Sopenharmony_ci MESA_SHADER_FRAGMENT); 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT && 351bf215546Sopenharmony_ci ctx->Const.GLSLVersionCompat >= 150) { 352bf215546Sopenharmony_ci new_state |= 353bf215546Sopenharmony_ci update_single_program_constants(ctx, ctx->GeometryProgram._Current, 354bf215546Sopenharmony_ci MESA_SHADER_GEOMETRY); 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci if (_mesa_has_ARB_tessellation_shader(ctx)) { 357bf215546Sopenharmony_ci new_state |= 358bf215546Sopenharmony_ci update_single_program_constants(ctx, ctx->TessCtrlProgram._Current, 359bf215546Sopenharmony_ci MESA_SHADER_TESS_CTRL) | 360bf215546Sopenharmony_ci update_single_program_constants(ctx, ctx->TessEvalProgram._Current, 361bf215546Sopenharmony_ci MESA_SHADER_TESS_EVAL); 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci } 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci return new_state; 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_cistatic void 370bf215546Sopenharmony_ciupdate_fixed_func_program_usage(struct gl_context *ctx) 371bf215546Sopenharmony_ci{ 372bf215546Sopenharmony_ci ctx->FragmentProgram._UsesTexEnvProgram = 373bf215546Sopenharmony_ci !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] && /* GLSL*/ 374bf215546Sopenharmony_ci !_mesa_arb_fragment_program_enabled(ctx) && 375bf215546Sopenharmony_ci !(_mesa_ati_fragment_shader_enabled(ctx) && 376bf215546Sopenharmony_ci ctx->ATIFragmentShader.Current->Program); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci ctx->VertexProgram._UsesTnlProgram = 379bf215546Sopenharmony_ci !ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] && /* GLSL */ 380bf215546Sopenharmony_ci !_mesa_arb_vertex_program_enabled(ctx); 381bf215546Sopenharmony_ci} 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci/** 385bf215546Sopenharmony_ci * Compute derived GL state. 386bf215546Sopenharmony_ci * If __struct gl_contextRec::NewState is non-zero then this function \b must 387bf215546Sopenharmony_ci * be called before rendering anything. 388bf215546Sopenharmony_ci * 389bf215546Sopenharmony_ci * Calls dd_function_table::UpdateState to perform any internal state 390bf215546Sopenharmony_ci * management necessary. 391bf215546Sopenharmony_ci * 392bf215546Sopenharmony_ci * \sa _mesa_update_modelview_project(), _mesa_update_texture(), 393bf215546Sopenharmony_ci * _mesa_update_buffer_bounds(), 394bf215546Sopenharmony_ci * _mesa_update_lighting() and _mesa_update_tnl_spaces(). 395bf215546Sopenharmony_ci */ 396bf215546Sopenharmony_civoid 397bf215546Sopenharmony_ci_mesa_update_state_locked( struct gl_context *ctx ) 398bf215546Sopenharmony_ci{ 399bf215546Sopenharmony_ci GLbitfield new_state = ctx->NewState; 400bf215546Sopenharmony_ci GLbitfield new_prog_state = 0x0; 401bf215546Sopenharmony_ci const GLbitfield checked_states = 402bf215546Sopenharmony_ci _NEW_BUFFERS | _NEW_MODELVIEW | _NEW_PROJECTION | _NEW_TEXTURE_MATRIX | 403bf215546Sopenharmony_ci _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM | 404bf215546Sopenharmony_ci _NEW_LIGHT_CONSTANTS | _NEW_POINT | _NEW_FF_VERT_PROGRAM | 405bf215546Sopenharmony_ci _NEW_FF_FRAG_PROGRAM | _NEW_TNL_SPACES; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci /* we can skip a bunch of state validation checks if the dirty 408bf215546Sopenharmony_ci * state matches one or more bits in 'computed_states'. 409bf215546Sopenharmony_ci */ 410bf215546Sopenharmony_ci if (!(new_state & checked_states)) 411bf215546Sopenharmony_ci goto out; 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_STATE) 414bf215546Sopenharmony_ci _mesa_print_state("_mesa_update_state", new_state); 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci if (new_state & _NEW_BUFFERS) 417bf215546Sopenharmony_ci _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer); 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci /* Handle Core and Compatibility contexts separately. */ 420bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT || 421bf215546Sopenharmony_ci ctx->API == API_OPENGLES) { 422bf215546Sopenharmony_ci /* Update derived state. */ 423bf215546Sopenharmony_ci if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 424bf215546Sopenharmony_ci _mesa_update_modelview_project( ctx, new_state ); 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (new_state & _NEW_TEXTURE_MATRIX) 427bf215546Sopenharmony_ci new_state |= _mesa_update_texture_matrices(ctx); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM)) 430bf215546Sopenharmony_ci new_state |= _mesa_update_texture_state(ctx); 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci if (new_state & _NEW_LIGHT_CONSTANTS) 433bf215546Sopenharmony_ci new_state |= _mesa_update_lighting(ctx); 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci /* ctx->_NeedEyeCoords is determined here. 436bf215546Sopenharmony_ci * 437bf215546Sopenharmony_ci * If the truth value of this variable has changed, update for the 438bf215546Sopenharmony_ci * new lighting space and recompute the positions of lights and the 439bf215546Sopenharmony_ci * normal transform. 440bf215546Sopenharmony_ci * 441bf215546Sopenharmony_ci * If the lighting space hasn't changed, may still need to recompute 442bf215546Sopenharmony_ci * light positions & normal transforms for other reasons. 443bf215546Sopenharmony_ci */ 444bf215546Sopenharmony_ci if (new_state & (_NEW_TNL_SPACES | _NEW_LIGHT_CONSTANTS | 445bf215546Sopenharmony_ci _NEW_MODELVIEW)) { 446bf215546Sopenharmony_ci if (_mesa_update_tnl_spaces(ctx, new_state)) 447bf215546Sopenharmony_ci new_state |= _NEW_FF_VERT_PROGRAM; 448bf215546Sopenharmony_ci } 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci if (new_state & _NEW_PROGRAM) 451bf215546Sopenharmony_ci update_fixed_func_program_usage(ctx); 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci /* Determine which states affect fixed-func vertex/fragment program. */ 454bf215546Sopenharmony_ci GLbitfield prog_flags = _NEW_PROGRAM; 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci if (ctx->FragmentProgram._UsesTexEnvProgram) { 457bf215546Sopenharmony_ci prog_flags |= _NEW_BUFFERS | _NEW_TEXTURE_OBJECT | 458bf215546Sopenharmony_ci _NEW_FF_FRAG_PROGRAM | _NEW_TEXTURE_STATE; 459bf215546Sopenharmony_ci } 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci if (ctx->VertexProgram._UsesTnlProgram) 462bf215546Sopenharmony_ci prog_flags |= _NEW_FF_VERT_PROGRAM; 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci if (new_state & prog_flags) { 465bf215546Sopenharmony_ci /* When we generate programs from fixed-function vertex/fragment state 466bf215546Sopenharmony_ci * this call may generate/bind a new program. If so, we need to 467bf215546Sopenharmony_ci * propogate the _NEW_PROGRAM flag to the driver. 468bf215546Sopenharmony_ci */ 469bf215546Sopenharmony_ci new_prog_state |= update_program(ctx); 470bf215546Sopenharmony_ci } 471bf215546Sopenharmony_ci } else { 472bf215546Sopenharmony_ci /* GL Core and GLES 2/3 contexts */ 473bf215546Sopenharmony_ci if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_PROGRAM)) 474bf215546Sopenharmony_ci _mesa_update_texture_state(ctx); 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci if (new_state & _NEW_PROGRAM) 477bf215546Sopenharmony_ci update_program(ctx); 478bf215546Sopenharmony_ci } 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci out: 481bf215546Sopenharmony_ci new_prog_state |= update_program_constants(ctx); 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci ctx->NewState |= new_prog_state; 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci /* 486bf215546Sopenharmony_ci * Give the driver a chance to act upon the new_state flags. 487bf215546Sopenharmony_ci * The driver might plug in different span functions, for example. 488bf215546Sopenharmony_ci * Also, this is where the driver can invalidate the state of any 489bf215546Sopenharmony_ci * active modules (such as swrast_setup, swrast, tnl, etc). 490bf215546Sopenharmony_ci */ 491bf215546Sopenharmony_ci st_invalidate_state(ctx); 492bf215546Sopenharmony_ci ctx->NewState = 0; 493bf215546Sopenharmony_ci} 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci/* This is the usual entrypoint for state updates: 497bf215546Sopenharmony_ci */ 498bf215546Sopenharmony_civoid 499bf215546Sopenharmony_ci_mesa_update_state( struct gl_context *ctx ) 500bf215546Sopenharmony_ci{ 501bf215546Sopenharmony_ci _mesa_lock_context_textures(ctx); 502bf215546Sopenharmony_ci _mesa_update_state_locked(ctx); 503bf215546Sopenharmony_ci _mesa_unlock_context_textures(ctx); 504bf215546Sopenharmony_ci} 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci/** 508bf215546Sopenharmony_ci * Used by drivers to tell core Mesa that the driver is going to 509bf215546Sopenharmony_ci * install/ use its own vertex program. In particular, this will 510bf215546Sopenharmony_ci * prevent generated fragment programs from using state vars instead 511bf215546Sopenharmony_ci * of ordinary varyings/inputs. 512bf215546Sopenharmony_ci */ 513bf215546Sopenharmony_civoid 514bf215546Sopenharmony_ci_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) 515bf215546Sopenharmony_ci{ 516bf215546Sopenharmony_ci if (ctx->VertexProgram._Overriden != flag) { 517bf215546Sopenharmony_ci ctx->VertexProgram._Overriden = flag; 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci /* Set one of the bits which will trigger fragment program 520bf215546Sopenharmony_ci * regeneration: 521bf215546Sopenharmony_ci */ 522bf215546Sopenharmony_ci ctx->NewState |= _NEW_PROGRAM; 523bf215546Sopenharmony_ci } 524bf215546Sopenharmony_ci} 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_cistatic void 528bf215546Sopenharmony_ciset_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) 529bf215546Sopenharmony_ci{ 530bf215546Sopenharmony_ci if (ctx->VertexProgram._VPMode == m) 531bf215546Sopenharmony_ci return; 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci /* On change we may get new maps into the current values */ 534bf215546Sopenharmony_ci ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; 535bf215546Sopenharmony_ci ctx->Array.NewVertexElements = true; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci /* Finally memorize the value */ 538bf215546Sopenharmony_ci ctx->VertexProgram._VPMode = m; 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci /* The gl_context::VertexProgram._VaryingInputs value is only used when in 541bf215546Sopenharmony_ci * VP_MODE_FF mode and the fixed-func pipeline is emulated by shaders. 542bf215546Sopenharmony_ci */ 543bf215546Sopenharmony_ci ctx->VertexProgram._VPModeOptimizesConstantAttribs = 544bf215546Sopenharmony_ci m == VP_MODE_FF; 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci /* Set a filter mask for the net enabled vao arrays. 547bf215546Sopenharmony_ci * This is to mask out arrays that would otherwise supersede required current 548bf215546Sopenharmony_ci * values for the fixed function shaders for example. 549bf215546Sopenharmony_ci */ 550bf215546Sopenharmony_ci switch (m) { 551bf215546Sopenharmony_ci case VP_MODE_FF: 552bf215546Sopenharmony_ci /* When no vertex program is active (or the vertex program is generated 553bf215546Sopenharmony_ci * from fixed-function state). We put the material values into the 554bf215546Sopenharmony_ci * generic slots. Since the vao has no material arrays, mute these 555bf215546Sopenharmony_ci * slots from the enabled arrays so that the current material values 556bf215546Sopenharmony_ci * are pulled instead of the vao arrays. 557bf215546Sopenharmony_ci */ 558bf215546Sopenharmony_ci ctx->VertexProgram._VPModeInputFilter = VERT_BIT_FF_ALL; 559bf215546Sopenharmony_ci break; 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci case VP_MODE_SHADER: 562bf215546Sopenharmony_ci /* There are no shaders in OpenGL ES 1.x, so this code path should be 563bf215546Sopenharmony_ci * impossible to reach. The meta code is careful to not use shaders in 564bf215546Sopenharmony_ci * ES1. 565bf215546Sopenharmony_ci */ 566bf215546Sopenharmony_ci assert(ctx->API != API_OPENGLES); 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci /* Other parts of the code assume that inputs[VERT_ATTRIB_POS] through 569bf215546Sopenharmony_ci * inputs[VERT_ATTRIB_GENERIC0-1] will be non-NULL. However, in OpenGL 570bf215546Sopenharmony_ci * ES 2.0+ or OpenGL core profile, none of these arrays should ever 571bf215546Sopenharmony_ci * be enabled. 572bf215546Sopenharmony_ci */ 573bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT) 574bf215546Sopenharmony_ci ctx->VertexProgram._VPModeInputFilter = VERT_BIT_ALL; 575bf215546Sopenharmony_ci else 576bf215546Sopenharmony_ci ctx->VertexProgram._VPModeInputFilter = VERT_BIT_GENERIC_ALL; 577bf215546Sopenharmony_ci break; 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci default: 580bf215546Sopenharmony_ci assert(0); 581bf215546Sopenharmony_ci } 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci /* Since we only track the varying inputs while being in fixed function 584bf215546Sopenharmony_ci * vertex processing mode, we may need to update fixed-func shaders 585bf215546Sopenharmony_ci * for zero-stride vertex attribs. 586bf215546Sopenharmony_ci */ 587bf215546Sopenharmony_ci _mesa_set_varying_vp_inputs(ctx, ctx->Array._DrawVAOEnabledAttribs); 588bf215546Sopenharmony_ci} 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci/** 592bf215546Sopenharmony_ci * Update ctx->VertexProgram._VPMode. 593bf215546Sopenharmony_ci * This is to distinguish whether we're running 594bf215546Sopenharmony_ci * a vertex program/shader, 595bf215546Sopenharmony_ci * a fixed-function TNL program or 596bf215546Sopenharmony_ci * a fixed function vertex transformation without any program. 597bf215546Sopenharmony_ci */ 598bf215546Sopenharmony_civoid 599bf215546Sopenharmony_ci_mesa_update_vertex_processing_mode(struct gl_context *ctx) 600bf215546Sopenharmony_ci{ 601bf215546Sopenharmony_ci if (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]) 602bf215546Sopenharmony_ci set_vertex_processing_mode(ctx, VP_MODE_SHADER); 603bf215546Sopenharmony_ci else if (_mesa_arb_vertex_program_enabled(ctx)) 604bf215546Sopenharmony_ci set_vertex_processing_mode(ctx, VP_MODE_SHADER); 605bf215546Sopenharmony_ci else 606bf215546Sopenharmony_ci set_vertex_processing_mode(ctx, VP_MODE_FF); 607bf215546Sopenharmony_ci} 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_civoid 611bf215546Sopenharmony_ci_mesa_reset_vertex_processing_mode(struct gl_context *ctx) 612bf215546Sopenharmony_ci{ 613bf215546Sopenharmony_ci ctx->VertexProgram._VPMode = -1; /* force the update */ 614bf215546Sopenharmony_ci _mesa_update_vertex_processing_mode(ctx); 615bf215546Sopenharmony_ci} 616