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