2000-02-02 19:15:19 +00:00
|
|
|
/*
|
|
|
|
* Mesa 3-D graphics library
|
|
|
|
*
|
2008-06-09 14:22:15 -06:00
|
|
|
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
|
2000-02-02 19:15:19 +00:00
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
|
* in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
2013-04-21 13:46:48 -07:00
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
2000-02-02 19:15:19 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2004-04-23 14:16:46 +00:00
|
|
|
/**
|
|
|
|
* \file state.c
|
|
|
|
* State management.
|
|
|
|
*
|
2010-10-12 12:26:10 -04:00
|
|
|
* This file manages recalculation of derived values in struct gl_context.
|
2004-04-23 14:16:46 +00:00
|
|
|
*/
|
|
|
|
|
2008-06-09 14:49:04 -06:00
|
|
|
|
2000-02-02 19:15:19 +00:00
|
|
|
#include "glheader.h"
|
2008-06-09 14:49:04 -06:00
|
|
|
#include "mtypes.h"
|
2012-01-20 10:55:15 -07:00
|
|
|
#include "arrayobj.h"
|
2000-02-02 19:15:19 +00:00
|
|
|
#include "context.h"
|
2008-06-09 14:49:04 -06:00
|
|
|
#include "debug.h"
|
|
|
|
#include "macros.h"
|
2008-09-20 08:26:11 -07:00
|
|
|
#include "ffvertex_prog.h"
|
2005-05-04 20:11:35 +00:00
|
|
|
#include "framebuffer.h"
|
2000-02-02 19:15:19 +00:00
|
|
|
#include "light.h"
|
|
|
|
#include "matrix.h"
|
|
|
|
#include "pixel.h"
|
2010-06-10 23:02:41 -06:00
|
|
|
#include "program/program.h"
|
|
|
|
#include "program/prog_parameter.h"
|
2011-11-15 12:01:18 -08:00
|
|
|
#include "shaderobj.h"
|
2000-02-02 19:15:19 +00:00
|
|
|
#include "state.h"
|
|
|
|
#include "stencil.h"
|
2008-06-09 14:49:04 -06:00
|
|
|
#include "texenvprogram.h"
|
2000-02-02 19:15:19 +00:00
|
|
|
#include "texobj.h"
|
|
|
|
#include "texstate.h"
|
2011-04-06 14:16:57 -06:00
|
|
|
#include "varray.h"
|
2017-06-07 13:26:16 +10:00
|
|
|
#include "vbo/vbo_context.h"
|
2014-09-21 18:09:21 +02:00
|
|
|
#include "viewport.h"
|
2013-03-28 01:50:21 +01:00
|
|
|
#include "blend.h"
|
2000-11-19 23:10:25 +00:00
|
|
|
|
2000-11-13 20:02:56 +00:00
|
|
|
|
2009-02-10 16:28:25 -07:00
|
|
|
/**
|
2014-03-07 10:39:39 +01:00
|
|
|
* Update the ctx->*Program._Current pointers to point to the
|
2017-03-23 23:59:56 +01:00
|
|
|
* current/active programs.
|
2011-06-22 08:12:10 -06:00
|
|
|
*
|
|
|
|
* Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
|
|
|
|
* programs or programs derived from fixed-function state.
|
2009-02-10 16:28:25 -07:00
|
|
|
*
|
|
|
|
* This function needs to be called after texture state validation in case
|
|
|
|
* we're generating a fragment program from fixed-function texture state.
|
2009-03-03 13:52:24 -07:00
|
|
|
*
|
|
|
|
* \return bitfield which will indicate _NEW_PROGRAM state if a new vertex
|
|
|
|
* or fragment program is being used.
|
2009-02-10 16:28:25 -07:00
|
|
|
*/
|
2009-03-03 13:52:24 -07:00
|
|
|
static GLbitfield
|
2010-10-12 12:26:10 -04:00
|
|
|
update_program(struct gl_context *ctx)
|
2009-02-10 16:28:25 -07:00
|
|
|
{
|
2016-10-31 22:39:17 +11:00
|
|
|
struct gl_program *vsProg =
|
2013-05-03 19:44:10 +02:00
|
|
|
ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
|
2016-10-31 22:39:17 +11:00
|
|
|
struct gl_program *tcsProg =
|
2014-03-07 10:39:39 +01:00
|
|
|
ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
|
2016-10-31 22:39:17 +11:00
|
|
|
struct gl_program *tesProg =
|
2014-03-07 10:39:39 +01:00
|
|
|
ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
|
2016-10-31 22:39:17 +11:00
|
|
|
struct gl_program *gsProg =
|
2013-05-03 19:44:10 +02:00
|
|
|
ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
|
2016-10-31 22:39:17 +11:00
|
|
|
struct gl_program *fsProg =
|
2013-05-03 19:44:10 +02:00
|
|
|
ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
|
2016-10-31 22:39:17 +11:00
|
|
|
struct gl_program *csProg =
|
2014-01-10 21:39:25 -08:00
|
|
|
ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
|
2016-10-19 12:30:09 +11:00
|
|
|
const struct gl_program *prevVP = ctx->VertexProgram._Current;
|
2016-10-19 13:23:37 +11:00
|
|
|
const struct gl_program *prevFP = ctx->FragmentProgram._Current;
|
2016-10-19 11:59:12 +11:00
|
|
|
const struct gl_program *prevGP = ctx->GeometryProgram._Current;
|
2016-10-19 11:13:52 +11:00
|
|
|
const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current;
|
2016-10-19 10:30:52 +11:00
|
|
|
const struct gl_program *prevTEP = ctx->TessEvalProgram._Current;
|
2016-10-19 12:11:06 +11:00
|
|
|
const struct gl_program *prevCP = ctx->ComputeProgram._Current;
|
2009-03-03 13:52:24 -07:00
|
|
|
GLbitfield new_state = 0x0;
|
2005-05-04 11:44:44 +00:00
|
|
|
|
2006-12-15 10:07:26 -07:00
|
|
|
/*
|
|
|
|
* Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
|
2008-12-17 18:05:03 -07:00
|
|
|
* pointers to the programs that should be used for rendering. If either
|
|
|
|
* is NULL, use fixed-function code paths.
|
2006-12-15 10:07:26 -07:00
|
|
|
*
|
|
|
|
* These programs may come from several sources. The priority is as
|
|
|
|
* follows:
|
|
|
|
* 1. OpenGL 2.0/ARB vertex/fragment shaders
|
|
|
|
* 2. ARB/NV vertex/fragment programs
|
2016-03-24 01:12:55 +01:00
|
|
|
* 3. ATI fragment shader
|
|
|
|
* 4. Programs derived from fixed-function state.
|
2008-09-20 08:26:11 -07:00
|
|
|
*
|
|
|
|
* Note: it's possible for a vertex shader to get used with a fragment
|
|
|
|
* program (and vice versa) here, but in practice that shouldn't ever
|
|
|
|
* come up, or matter.
|
2006-12-15 10:07:26 -07:00
|
|
|
*/
|
|
|
|
|
2016-10-31 22:39:17 +11:00
|
|
|
if (fsProg) {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* Use GLSL fragment shader */
|
2016-10-31 22:39:17 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg);
|
2016-10-19 13:23:37 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
|
|
|
|
NULL);
|
2006-12-15 10:07:26 -07:00
|
|
|
}
|
2017-06-09 23:27:41 +02:00
|
|
|
else if (_mesa_arb_fragment_program_enabled(ctx)) {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* Use user-defined fragment program */
|
2016-10-19 13:23:37 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
|
|
|
|
ctx->FragmentProgram.Current);
|
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
|
|
|
|
NULL);
|
2008-11-13 13:16:03 +00:00
|
|
|
}
|
2017-06-09 23:27:41 +02:00
|
|
|
else if (_mesa_ati_fragment_shader_enabled(ctx) &&
|
2016-03-24 01:12:55 +01:00
|
|
|
ctx->ATIFragmentShader.Current->Program) {
|
|
|
|
/* Use the enabled ATI fragment shader's associated program */
|
2016-10-19 13:23:37 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
|
|
|
|
ctx->ATIFragmentShader.Current->Program);
|
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
|
|
|
|
NULL);
|
2016-03-24 01:12:55 +01:00
|
|
|
}
|
2008-11-13 13:16:03 +00:00
|
|
|
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* Use fragment program generated from fixed-function state */
|
2010-11-01 13:16:21 -07:00
|
|
|
struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx);
|
|
|
|
|
2016-10-19 13:23:37 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
|
|
|
|
f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
|
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
|
|
|
|
f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
|
2008-11-13 13:16:03 +00:00
|
|
|
}
|
2006-12-15 10:07:26 -07:00
|
|
|
else {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* No fragment program */
|
2016-10-19 13:23:37 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL);
|
|
|
|
_mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
|
|
|
|
NULL);
|
2008-11-13 13:16:03 +00:00
|
|
|
}
|
2008-09-20 08:26:11 -07:00
|
|
|
|
2016-10-31 22:39:17 +11:00
|
|
|
if (gsProg) {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* Use GLSL geometry shader */
|
2016-10-31 22:39:17 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg);
|
2010-06-28 17:31:21 -04:00
|
|
|
} else {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* No geometry program */
|
2016-10-19 11:59:12 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL);
|
2010-06-28 17:31:21 -04:00
|
|
|
}
|
|
|
|
|
2016-10-31 22:39:17 +11:00
|
|
|
if (tesProg) {
|
2014-03-07 10:39:39 +01:00
|
|
|
/* Use GLSL tessellation evaluation shader */
|
2016-10-31 22:39:17 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg);
|
2014-03-07 10:39:39 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* No tessellation evaluation program */
|
2016-10-19 10:30:52 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL);
|
2014-03-07 10:39:39 +01:00
|
|
|
}
|
|
|
|
|
2016-10-31 22:39:17 +11:00
|
|
|
if (tcsProg) {
|
2014-03-07 10:39:39 +01:00
|
|
|
/* Use GLSL tessellation control shader */
|
2016-10-31 22:39:17 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg);
|
2014-03-07 10:39:39 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* No tessellation control program */
|
2016-10-19 11:13:52 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL);
|
2014-03-07 10:39:39 +01:00
|
|
|
}
|
|
|
|
|
2008-11-13 13:16:03 +00:00
|
|
|
/* Examine vertex program after fragment program as
|
|
|
|
* _mesa_get_fixed_func_vertex_program() needs to know active
|
|
|
|
* fragprog inputs.
|
|
|
|
*/
|
2016-10-31 22:39:17 +11:00
|
|
|
if (vsProg) {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* Use GLSL vertex shader */
|
2016-10-31 22:39:17 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg);
|
2008-11-13 13:16:03 +00:00
|
|
|
}
|
2017-06-09 23:27:41 +02:00
|
|
|
else if (_mesa_arb_vertex_program_enabled(ctx)) {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* Use user-defined vertex program */
|
2016-10-19 12:30:09 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->VertexProgram._Current,
|
|
|
|
ctx->VertexProgram.Current);
|
2008-11-13 13:16:03 +00:00
|
|
|
}
|
|
|
|
else if (ctx->VertexProgram._MaintainTnlProgram) {
|
2011-06-22 08:12:10 -06:00
|
|
|
/* Use vertex program generated from fixed-function state */
|
2016-10-19 12:30:09 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->VertexProgram._Current,
|
|
|
|
_mesa_get_fixed_func_vertex_program(ctx));
|
|
|
|
_mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram,
|
|
|
|
ctx->VertexProgram._Current);
|
2008-11-13 13:16:03 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* no vertex program */
|
2016-10-19 12:30:09 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL);
|
2005-05-04 11:44:44 +00:00
|
|
|
}
|
2007-03-27 09:51:52 -06:00
|
|
|
|
2016-10-31 22:39:17 +11:00
|
|
|
if (csProg) {
|
2014-01-10 21:39:25 -08:00
|
|
|
/* Use GLSL compute shader */
|
2016-10-31 22:39:17 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg);
|
2014-01-10 21:39:25 -08:00
|
|
|
} else {
|
|
|
|
/* no compute program */
|
2016-10-19 12:11:06 +11:00
|
|
|
_mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL);
|
2014-01-10 21:39:25 -08:00
|
|
|
}
|
|
|
|
|
2008-09-20 08:26:11 -07:00
|
|
|
/* Let the driver know what's happening:
|
|
|
|
*/
|
2017-03-23 23:59:56 +01:00
|
|
|
if (ctx->FragmentProgram._Current != prevFP ||
|
|
|
|
ctx->VertexProgram._Current != prevVP ||
|
|
|
|
ctx->GeometryProgram._Current != prevGP ||
|
|
|
|
ctx->TessEvalProgram._Current != prevTEP ||
|
|
|
|
ctx->TessCtrlProgram._Current != prevTCP ||
|
|
|
|
ctx->ComputeProgram._Current != prevCP)
|
2009-03-03 13:52:24 -07:00
|
|
|
new_state |= _NEW_PROGRAM;
|
2014-01-10 21:39:25 -08:00
|
|
|
|
2009-03-03 13:52:24 -07:00
|
|
|
return new_state;
|
2004-04-23 14:16:46 +00:00
|
|
|
}
|
|
|
|
|
2003-11-10 19:08:37 +00:00
|
|
|
|
2009-04-21 15:56:45 -06:00
|
|
|
/**
|
|
|
|
* Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0.
|
|
|
|
*/
|
|
|
|
static GLbitfield
|
2010-10-12 12:26:10 -04:00
|
|
|
update_program_constants(struct gl_context *ctx)
|
2009-04-21 15:56:45 -06:00
|
|
|
{
|
|
|
|
GLbitfield new_state = 0x0;
|
|
|
|
|
|
|
|
if (ctx->FragmentProgram._Current) {
|
|
|
|
const struct gl_program_parameter_list *params =
|
2016-10-19 13:23:37 +11:00
|
|
|
ctx->FragmentProgram._Current->Parameters;
|
2009-04-21 15:56:45 -06:00
|
|
|
if (params && params->StateFlags & ctx->NewState) {
|
|
|
|
new_state |= _NEW_PROGRAM_CONSTANTS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-07 10:39:39 +01:00
|
|
|
/* Don't handle tessellation and geometry shaders here. They don't use
|
|
|
|
* any state constants.
|
2015-06-14 16:37:02 +02:00
|
|
|
*/
|
2010-06-28 17:31:21 -04:00
|
|
|
|
2009-04-21 15:56:45 -06:00
|
|
|
if (ctx->VertexProgram._Current) {
|
|
|
|
const struct gl_program_parameter_list *params =
|
2016-10-19 12:30:09 +11:00
|
|
|
ctx->VertexProgram._Current->Parameters;
|
2009-04-21 15:56:45 -06:00
|
|
|
if (params && params->StateFlags & ctx->NewState) {
|
|
|
|
new_state |= _NEW_PROGRAM_CONSTANTS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return new_state;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-02-26 17:16:12 +00:00
|
|
|
/**
|
2006-12-15 10:07:26 -07:00
|
|
|
* Compute derived GL state.
|
2010-10-12 12:26:10 -04:00
|
|
|
* If __struct gl_contextRec::NewState is non-zero then this function \b must
|
2006-12-15 10:07:26 -07:00
|
|
|
* be called before rendering anything.
|
2000-12-26 05:09:27 +00:00
|
|
|
*
|
2005-02-26 17:16:12 +00:00
|
|
|
* Calls dd_function_table::UpdateState to perform any internal state
|
|
|
|
* management necessary.
|
2003-07-17 13:43:59 +00:00
|
|
|
*
|
|
|
|
* \sa _mesa_update_modelview_project(), _mesa_update_texture(),
|
2006-12-13 15:31:14 -07:00
|
|
|
* _mesa_update_buffer_bounds(),
|
2005-02-26 17:16:12 +00:00
|
|
|
* _mesa_update_lighting() and _mesa_update_tnl_spaces().
|
2000-11-13 20:02:56 +00:00
|
|
|
*/
|
2005-02-26 17:16:12 +00:00
|
|
|
void
|
2010-10-12 12:26:10 -04:00
|
|
|
_mesa_update_state_locked( struct gl_context *ctx )
|
2000-11-13 20:02:56 +00:00
|
|
|
{
|
2006-01-09 17:57:47 +00:00
|
|
|
GLbitfield new_state = ctx->NewState;
|
2008-09-20 08:26:11 -07:00
|
|
|
GLbitfield prog_flags = _NEW_PROGRAM;
|
2009-03-03 13:52:24 -07:00
|
|
|
GLbitfield new_prog_state = 0x0;
|
2015-10-14 09:10:19 -06:00
|
|
|
const GLbitfield computed_states = ~(_NEW_CURRENT_ATTRIB | _NEW_LINE);
|
2000-11-13 20:02:56 +00:00
|
|
|
|
2015-10-14 09:10:19 -06:00
|
|
|
/* we can skip a bunch of state validation checks if the dirty
|
|
|
|
* state matches one or more bits in 'computed_states'.
|
|
|
|
*/
|
|
|
|
if ((new_state & computed_states) == 0)
|
2008-10-03 13:55:40 +01:00
|
|
|
goto out;
|
|
|
|
|
2000-11-13 20:02:56 +00:00
|
|
|
if (MESA_VERBOSE & VERBOSE_STATE)
|
2002-04-09 16:56:50 +00:00
|
|
|
_mesa_print_state("_mesa_update_state", new_state);
|
2000-11-13 20:02:56 +00:00
|
|
|
|
2009-02-10 16:28:25 -07:00
|
|
|
/* Determine which state flags effect vertex/fragment program state */
|
2009-02-10 15:35:25 -07:00
|
|
|
if (ctx->FragmentProgram._MaintainTexEnvProgram) {
|
2017-03-23 22:59:08 +01:00
|
|
|
prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE_OBJECT | _NEW_FOG |
|
2012-04-16 04:21:03 +02:00
|
|
|
_NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT |
|
|
|
|
_NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP |
|
2017-03-23 22:59:08 +01:00
|
|
|
_NEW_COLOR | _NEW_TEXTURE_STATE);
|
2009-02-10 15:35:25 -07:00
|
|
|
}
|
|
|
|
if (ctx->VertexProgram._MaintainTnlProgram) {
|
2017-03-23 22:59:08 +01:00
|
|
|
prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE_OBJECT |
|
2012-04-16 04:21:03 +02:00
|
|
|
_NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT |
|
2017-03-23 22:59:08 +01:00
|
|
|
_NEW_FOG | _NEW_LIGHT | _NEW_TEXTURE_STATE |
|
2009-02-10 15:35:25 -07:00
|
|
|
_MESA_NEW_NEED_EYE_COORDS);
|
|
|
|
}
|
2009-02-10 16:28:25 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Now update derived state info
|
|
|
|
*/
|
2003-07-17 13:43:59 +00:00
|
|
|
if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
|
|
|
|
_mesa_update_modelview_project( ctx, new_state );
|
2000-11-13 20:02:56 +00:00
|
|
|
|
2017-03-23 22:35:03 +01:00
|
|
|
if (new_state & _NEW_TEXTURE_MATRIX)
|
|
|
|
_mesa_update_texture_matrices(ctx);
|
|
|
|
|
2017-03-23 22:59:08 +01:00
|
|
|
if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM))
|
2017-03-23 22:35:03 +01:00
|
|
|
_mesa_update_texture_state(ctx);
|
2000-02-02 19:15:19 +00:00
|
|
|
|
2007-10-29 17:36:39 -06:00
|
|
|
if (new_state & _NEW_BUFFERS)
|
2015-02-03 11:03:01 -08:00
|
|
|
_mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
|
2005-05-04 20:11:35 +00:00
|
|
|
|
2000-11-22 07:32:16 +00:00
|
|
|
if (new_state & _NEW_LIGHT)
|
2001-03-03 20:33:27 +00:00
|
|
|
_mesa_update_lighting( ctx );
|
2000-02-02 19:15:19 +00:00
|
|
|
|
2011-03-23 09:04:22 -06:00
|
|
|
if (new_state & _NEW_PIXEL)
|
2017-06-06 22:58:12 +02:00
|
|
|
_mesa_update_pixel( ctx );
|
2000-02-02 19:15:19 +00:00
|
|
|
|
2003-07-23 21:21:30 +00:00
|
|
|
/* ctx->_NeedEyeCoords is now up to date.
|
2000-11-13 20:02:56 +00:00
|
|
|
*
|
2000-12-26 05:09:27 +00:00
|
|
|
* If the truth value of this variable has changed, update for the
|
|
|
|
* new lighting space and recompute the positions of lights and the
|
2000-11-13 20:02:56 +00:00
|
|
|
* normal transform.
|
2000-11-22 07:32:16 +00:00
|
|
|
*
|
2000-11-13 20:02:56 +00:00
|
|
|
* If the lighting space hasn't changed, may still need to recompute
|
2001-03-12 00:48:37 +00:00
|
|
|
* light positions & normal transforms for other reasons.
|
2000-11-13 20:02:56 +00:00
|
|
|
*/
|
2003-07-17 13:43:59 +00:00
|
|
|
if (new_state & _MESA_NEW_NEED_EYE_COORDS)
|
|
|
|
_mesa_update_tnl_spaces( ctx, new_state );
|
2000-11-13 20:02:56 +00:00
|
|
|
|
2009-03-03 13:52:24 -07:00
|
|
|
if (new_state & prog_flags) {
|
|
|
|
/* When we generate programs from fixed-function vertex/fragment state
|
|
|
|
* this call may generate/bind a new program. If so, we need to
|
|
|
|
* propogate the _NEW_PROGRAM flag to the driver.
|
|
|
|
*/
|
|
|
|
new_prog_state |= update_program( ctx );
|
|
|
|
}
|
2008-09-20 08:26:11 -07:00
|
|
|
|
2013-04-09 20:54:25 +02:00
|
|
|
if (new_state & _NEW_ARRAY)
|
2014-02-01 20:48:51 -08:00
|
|
|
_mesa_update_vao_client_arrays(ctx, ctx->Array.VAO);
|
2013-04-09 20:54:25 +02:00
|
|
|
|
2009-04-21 15:56:45 -06:00
|
|
|
out:
|
|
|
|
new_prog_state |= update_program_constants(ctx);
|
|
|
|
|
2017-06-07 13:26:16 +10:00
|
|
|
ctx->NewState |= new_prog_state;
|
|
|
|
vbo_exec_invalidate_state(ctx);
|
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
/*
|
2004-01-20 23:55:45 +00:00
|
|
|
* Give the driver a chance to act upon the new_state flags.
|
|
|
|
* The driver might plug in different span functions, for example.
|
|
|
|
* Also, this is where the driver can invalidate the state of any
|
|
|
|
* active modules (such as swrast_setup, swrast, tnl, etc).
|
2000-11-16 21:05:34 +00:00
|
|
|
*/
|
2017-06-07 12:19:13 +10:00
|
|
|
ctx->Driver.UpdateState(ctx);
|
2000-02-02 19:15:19 +00:00
|
|
|
ctx->NewState = 0;
|
2014-02-01 19:14:38 -08:00
|
|
|
ctx->Array.VAO->NewArrays = 0x0;
|
2000-02-02 19:15:19 +00:00
|
|
|
}
|
2002-02-13 00:53:19 +00:00
|
|
|
|
2006-11-01 14:21:57 +00:00
|
|
|
|
|
|
|
/* This is the usual entrypoint for state updates:
|
|
|
|
*/
|
|
|
|
void
|
2010-10-12 12:26:10 -04:00
|
|
|
_mesa_update_state( struct gl_context *ctx )
|
2006-11-01 14:21:57 +00:00
|
|
|
{
|
|
|
|
_mesa_lock_context_textures(ctx);
|
|
|
|
_mesa_update_state_locked(ctx);
|
|
|
|
_mesa_unlock_context_textures(ctx);
|
|
|
|
}
|
2008-10-03 17:30:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-10 13:39:14 -06:00
|
|
|
/**
|
|
|
|
* Want to figure out which fragment program inputs are actually
|
2008-10-03 17:30:59 +01:00
|
|
|
* constant/current values from ctx->Current. These should be
|
|
|
|
* referenced as a tracked state variable rather than a fragment
|
|
|
|
* program input, to save the overhead of putting a constant value in
|
|
|
|
* every submitted vertex, transferring it to hardware, interpolating
|
|
|
|
* it across the triangle, etc...
|
|
|
|
*
|
|
|
|
* When there is a VP bound, just use vp->outputs. But when we're
|
|
|
|
* generating vp from fixed function state, basically want to
|
|
|
|
* calculate:
|
|
|
|
*
|
|
|
|
* vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) |
|
|
|
|
* potential_vp_outputs )
|
|
|
|
*
|
|
|
|
* Where potential_vp_outputs is calculated by looking at enabled
|
|
|
|
* texgen, etc.
|
|
|
|
*
|
|
|
|
* The generated fragment program should then only declare inputs that
|
|
|
|
* may vary or otherwise differ from the ctx->Current values.
|
|
|
|
* Otherwise, the fp should track them as state values instead.
|
|
|
|
*/
|
|
|
|
void
|
2010-10-12 12:26:10 -04:00
|
|
|
_mesa_set_varying_vp_inputs( struct gl_context *ctx,
|
2011-10-31 18:32:59 +01:00
|
|
|
GLbitfield64 varying_inputs )
|
2008-10-03 17:30:59 +01:00
|
|
|
{
|
|
|
|
if (ctx->varying_vp_inputs != varying_inputs) {
|
|
|
|
ctx->varying_vp_inputs = varying_inputs;
|
2012-04-16 16:04:52 +02:00
|
|
|
|
|
|
|
/* Only the fixed-func generated programs need to use the flag
|
|
|
|
* and the fixed-func fragment program uses it only if there is also
|
|
|
|
* a fixed-func vertex program, so this only depends on the latter.
|
|
|
|
*
|
|
|
|
* It's okay to check the VP pointer here, because this is called after
|
|
|
|
* _mesa_update_state in the vbo module. */
|
2012-10-01 20:11:38 -07:00
|
|
|
if (ctx->VertexProgram._TnlProgram ||
|
|
|
|
ctx->FragmentProgram._TexEnvProgram) {
|
2012-04-16 16:04:52 +02:00
|
|
|
ctx->NewState |= _NEW_VARYING_VP_INPUTS;
|
|
|
|
}
|
2015-04-07 22:04:58 +03:00
|
|
|
/*printf("%s %x\n", __func__, varying_inputs);*/
|
2008-10-10 13:39:14 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used by drivers to tell core Mesa that the driver is going to
|
|
|
|
* install/ use its own vertex program. In particular, this will
|
|
|
|
* prevent generated fragment programs from using state vars instead
|
|
|
|
* of ordinary varyings/inputs.
|
|
|
|
*/
|
|
|
|
void
|
2010-10-12 12:26:10 -04:00
|
|
|
_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag)
|
2008-10-10 13:39:14 -06:00
|
|
|
{
|
|
|
|
if (ctx->VertexProgram._Overriden != flag) {
|
|
|
|
ctx->VertexProgram._Overriden = flag;
|
|
|
|
|
|
|
|
/* Set one of the bits which will trigger fragment program
|
|
|
|
* regeneration:
|
|
|
|
*/
|
2009-08-07 08:53:53 -06:00
|
|
|
ctx->NewState |= _NEW_PROGRAM;
|
2008-10-03 17:30:59 +01:00
|
|
|
}
|
|
|
|
}
|