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-2007 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 * \file prog_statevars.c
27*61046927SAndroid Build Coastguard Worker * Program state variable management.
28*61046927SAndroid Build Coastguard Worker * \author Brian Paul
29*61046927SAndroid Build Coastguard Worker */
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include <stdio.h>
33*61046927SAndroid Build Coastguard Worker #include <stddef.h>
34*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
35*61046927SAndroid Build Coastguard Worker #include "main/context.h"
36*61046927SAndroid Build Coastguard Worker #include "main/blend.h"
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker #include "main/macros.h"
39*61046927SAndroid Build Coastguard Worker #include "main/fbobject.h"
40*61046927SAndroid Build Coastguard Worker #include "prog_statevars.h"
41*61046927SAndroid Build Coastguard Worker #include "prog_parameter.h"
42*61046927SAndroid Build Coastguard Worker #include "main/samplerobj.h"
43*61046927SAndroid Build Coastguard Worker #include "main/framebuffer.h"
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker #define ONE_DIV_SQRT_LN2 (1.201122408786449815)
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
copy_matrix(float * value,const float * m,unsigned firstRow,unsigned lastRow)49*61046927SAndroid Build Coastguard Worker copy_matrix(float *value, const float *m, unsigned firstRow, unsigned lastRow)
50*61046927SAndroid Build Coastguard Worker {
51*61046927SAndroid Build Coastguard Worker unsigned i, row;
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker assert(firstRow < 4);
54*61046927SAndroid Build Coastguard Worker assert(lastRow < 4);
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker for (i = 0, row = firstRow; row <= lastRow; row++) {
57*61046927SAndroid Build Coastguard Worker value[i++] = m[row + 0];
58*61046927SAndroid Build Coastguard Worker value[i++] = m[row + 4];
59*61046927SAndroid Build Coastguard Worker value[i++] = m[row + 8];
60*61046927SAndroid Build Coastguard Worker value[i++] = m[row + 12];
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker }
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
copy_matrix_transposed(float * value,const float * m,unsigned firstRow,unsigned lastRow)65*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(float *value, const float *m, unsigned firstRow, unsigned lastRow)
66*61046927SAndroid Build Coastguard Worker {
67*61046927SAndroid Build Coastguard Worker assert(firstRow < 4);
68*61046927SAndroid Build Coastguard Worker assert(lastRow < 4);
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker memcpy(value, &m[firstRow * 4],
71*61046927SAndroid Build Coastguard Worker (lastRow - firstRow + 1) * 4 * sizeof(GLfloat));
72*61046927SAndroid Build Coastguard Worker }
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker /**
75*61046927SAndroid Build Coastguard Worker * Use the list of tokens in the state[] array to find global GL state
76*61046927SAndroid Build Coastguard Worker * and return it in <value>. Usually, four values are returned in <value>
77*61046927SAndroid Build Coastguard Worker * but matrix queries may return as many as 16 values.
78*61046927SAndroid Build Coastguard Worker * This function is used for ARB vertex/fragment programs.
79*61046927SAndroid Build Coastguard Worker * The program parser will produce the state[] values.
80*61046927SAndroid Build Coastguard Worker */
81*61046927SAndroid Build Coastguard Worker static void
fetch_state(struct gl_context * ctx,const gl_state_index16 state[],gl_constant_value * val)82*61046927SAndroid Build Coastguard Worker fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
83*61046927SAndroid Build Coastguard Worker gl_constant_value *val)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker GLfloat *value = &val->f;
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker switch (state[0]) {
88*61046927SAndroid Build Coastguard Worker case STATE_MATERIAL:
89*61046927SAndroid Build Coastguard Worker {
90*61046927SAndroid Build Coastguard Worker /* state[1] is MAT_ATTRIB_FRONT_* */
91*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
92*61046927SAndroid Build Coastguard Worker const struct gl_material *mat = &ctx->Light.Material;
93*61046927SAndroid Build Coastguard Worker assert(index >= MAT_ATTRIB_FRONT_AMBIENT &&
94*61046927SAndroid Build Coastguard Worker index <= MAT_ATTRIB_BACK_SHININESS);
95*61046927SAndroid Build Coastguard Worker if (index >= MAT_ATTRIB_FRONT_SHININESS) {
96*61046927SAndroid Build Coastguard Worker value[0] = mat->Attrib[index][0];
97*61046927SAndroid Build Coastguard Worker value[1] = 0.0F;
98*61046927SAndroid Build Coastguard Worker value[2] = 0.0F;
99*61046927SAndroid Build Coastguard Worker value[3] = 1.0F;
100*61046927SAndroid Build Coastguard Worker } else {
101*61046927SAndroid Build Coastguard Worker COPY_4V(value, mat->Attrib[index]);
102*61046927SAndroid Build Coastguard Worker }
103*61046927SAndroid Build Coastguard Worker return;
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker case STATE_LIGHT:
106*61046927SAndroid Build Coastguard Worker {
107*61046927SAndroid Build Coastguard Worker /* state[1] is the light number */
108*61046927SAndroid Build Coastguard Worker const GLuint ln = (GLuint) state[1];
109*61046927SAndroid Build Coastguard Worker /* state[2] is the light attribute */
110*61046927SAndroid Build Coastguard Worker const unsigned index = state[2] - STATE_AMBIENT;
111*61046927SAndroid Build Coastguard Worker assert(index < 8);
112*61046927SAndroid Build Coastguard Worker if (index != STATE_SPOT_CUTOFF)
113*61046927SAndroid Build Coastguard Worker COPY_4V(value, (float*)&ctx->Light.LightSource[ln] + index * 4);
114*61046927SAndroid Build Coastguard Worker else
115*61046927SAndroid Build Coastguard Worker value[0] = ctx->Light.LightSource[ln].SpotCutoff;
116*61046927SAndroid Build Coastguard Worker return;
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ARRAY: {
119*61046927SAndroid Build Coastguard Worker /* This must be exact because it must match the gl_LightSource layout
120*61046927SAndroid Build Coastguard Worker * in GLSL.
121*61046927SAndroid Build Coastguard Worker */
122*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(sizeof(struct gl_light_uniforms) == 29 * 4);
123*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(ctx->Light.LightSourceData) == 29 * MAX_LIGHTS);
124*61046927SAndroid Build Coastguard Worker /* state[1] is the index of the first value */
125*61046927SAndroid Build Coastguard Worker /* state[2] is the number of values */
126*61046927SAndroid Build Coastguard Worker assert(state[1] + state[2] <= ARRAY_SIZE(ctx->Light.LightSourceData));
127*61046927SAndroid Build Coastguard Worker memcpy(value, &ctx->Light.LightSourceData[state[1]],
128*61046927SAndroid Build Coastguard Worker state[2] * sizeof(float));
129*61046927SAndroid Build Coastguard Worker return;
130*61046927SAndroid Build Coastguard Worker }
131*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ATTENUATION_ARRAY: {
132*61046927SAndroid Build Coastguard Worker const unsigned first = state[1];
133*61046927SAndroid Build Coastguard Worker const unsigned num_lights = state[2];
134*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_lights; i++) {
135*61046927SAndroid Build Coastguard Worker COPY_4V(value,
136*61046927SAndroid Build Coastguard Worker &ctx->Light.LightSource[first + i].ConstantAttenuation);
137*61046927SAndroid Build Coastguard Worker value += 4;
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker return;
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_AMBIENT:
142*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Light.Model.Ambient);
143*61046927SAndroid Build Coastguard Worker return;
144*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_SCENECOLOR:
145*61046927SAndroid Build Coastguard Worker if (state[1] == 0) {
146*61046927SAndroid Build Coastguard Worker /* front */
147*61046927SAndroid Build Coastguard Worker GLint i;
148*61046927SAndroid Build Coastguard Worker for (i = 0; i < 3; i++) {
149*61046927SAndroid Build Coastguard Worker value[i] = ctx->Light.Model.Ambient[i]
150*61046927SAndroid Build Coastguard Worker * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
151*61046927SAndroid Build Coastguard Worker + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
152*61046927SAndroid Build Coastguard Worker }
153*61046927SAndroid Build Coastguard Worker value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker else {
156*61046927SAndroid Build Coastguard Worker /* back */
157*61046927SAndroid Build Coastguard Worker GLint i;
158*61046927SAndroid Build Coastguard Worker for (i = 0; i < 3; i++) {
159*61046927SAndroid Build Coastguard Worker value[i] = ctx->Light.Model.Ambient[i]
160*61046927SAndroid Build Coastguard Worker * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
161*61046927SAndroid Build Coastguard Worker + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
164*61046927SAndroid Build Coastguard Worker }
165*61046927SAndroid Build Coastguard Worker return;
166*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD:
167*61046927SAndroid Build Coastguard Worker {
168*61046927SAndroid Build Coastguard Worker const GLuint ln = (GLuint) state[1];
169*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[2];
170*61046927SAndroid Build Coastguard Worker const GLuint attr = (index / 2) * 4;
171*61046927SAndroid Build Coastguard Worker assert(index >= MAT_ATTRIB_FRONT_AMBIENT &&
172*61046927SAndroid Build Coastguard Worker index <= MAT_ATTRIB_BACK_SPECULAR);
173*61046927SAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) {
174*61046927SAndroid Build Coastguard Worker /* We want attr to access out of bounds into the following Diffuse
175*61046927SAndroid Build Coastguard Worker * and Specular fields. This is guaranteed to work because
176*61046927SAndroid Build Coastguard Worker * STATE_LIGHT and STATE_LIGHT_ARRAY also rely on this memory
177*61046927SAndroid Build Coastguard Worker * layout.
178*61046927SAndroid Build Coastguard Worker */
179*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(offsetof(struct gl_light_uniforms, Ambient) + 16 ==
180*61046927SAndroid Build Coastguard Worker offsetof(struct gl_light_uniforms, Diffuse));
181*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(offsetof(struct gl_light_uniforms, Diffuse) + 16 ==
182*61046927SAndroid Build Coastguard Worker offsetof(struct gl_light_uniforms, Specular));
183*61046927SAndroid Build Coastguard Worker value[i] = ctx->Light.LightSource[ln].Ambient[attr + i] *
184*61046927SAndroid Build Coastguard Worker ctx->Light.Material.Attrib[index][i];
185*61046927SAndroid Build Coastguard Worker }
186*61046927SAndroid Build Coastguard Worker /* [3] = material alpha */
187*61046927SAndroid Build Coastguard Worker value[3] = ctx->Light.Material.Attrib[index][3];
188*61046927SAndroid Build Coastguard Worker return;
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_FRONT: {
191*61046927SAndroid Build Coastguard Worker const unsigned first_light = state[1];
192*61046927SAndroid Build Coastguard Worker const unsigned num_lights = state[2];
193*61046927SAndroid Build Coastguard Worker
194*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_lights; i++) {
195*61046927SAndroid Build Coastguard Worker unsigned light = first_light + i;
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker for (unsigned attrib = MAT_ATTRIB_FRONT_AMBIENT;
198*61046927SAndroid Build Coastguard Worker attrib <= MAT_ATTRIB_FRONT_SPECULAR; attrib += 2) {
199*61046927SAndroid Build Coastguard Worker for (int chan = 0; chan < 3; chan++) {
200*61046927SAndroid Build Coastguard Worker /* We want offset to access out of bounds into the following
201*61046927SAndroid Build Coastguard Worker * Diffuse and Specular fields. This is guaranteed to work
202*61046927SAndroid Build Coastguard Worker * because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely
203*61046927SAndroid Build Coastguard Worker * on this memory layout.
204*61046927SAndroid Build Coastguard Worker */
205*61046927SAndroid Build Coastguard Worker unsigned offset = (attrib / 2) * 4 + chan;
206*61046927SAndroid Build Coastguard Worker *value++ =
207*61046927SAndroid Build Coastguard Worker (&ctx->Light.LightSource[light].Ambient[0])[offset] *
208*61046927SAndroid Build Coastguard Worker ctx->Light.Material.Attrib[attrib][chan];
209*61046927SAndroid Build Coastguard Worker }
210*61046927SAndroid Build Coastguard Worker /* [3] = material alpha */
211*61046927SAndroid Build Coastguard Worker *value++ = ctx->Light.Material.Attrib[attrib][3];
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker }
214*61046927SAndroid Build Coastguard Worker return;
215*61046927SAndroid Build Coastguard Worker }
216*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_BACK: {
217*61046927SAndroid Build Coastguard Worker const unsigned first_light = state[1];
218*61046927SAndroid Build Coastguard Worker const unsigned num_lights = state[2];
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_lights; i++) {
221*61046927SAndroid Build Coastguard Worker unsigned light = first_light + i;
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker for (unsigned attrib = MAT_ATTRIB_BACK_AMBIENT;
224*61046927SAndroid Build Coastguard Worker attrib <= MAT_ATTRIB_BACK_SPECULAR; attrib += 2) {
225*61046927SAndroid Build Coastguard Worker for (int chan = 0; chan < 3; chan++) {
226*61046927SAndroid Build Coastguard Worker /* We want offset to access out of bounds into the following
227*61046927SAndroid Build Coastguard Worker * Diffuse and Specular fields. This is guaranteed to work
228*61046927SAndroid Build Coastguard Worker * because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely
229*61046927SAndroid Build Coastguard Worker * on this memory layout.
230*61046927SAndroid Build Coastguard Worker */
231*61046927SAndroid Build Coastguard Worker unsigned offset = (attrib / 2) * 4 + chan;
232*61046927SAndroid Build Coastguard Worker *value++ =
233*61046927SAndroid Build Coastguard Worker (&ctx->Light.LightSource[light].Ambient[0])[offset] *
234*61046927SAndroid Build Coastguard Worker ctx->Light.Material.Attrib[attrib][chan];
235*61046927SAndroid Build Coastguard Worker }
236*61046927SAndroid Build Coastguard Worker /* [3] = material alpha */
237*61046927SAndroid Build Coastguard Worker *value++ = ctx->Light.Material.Attrib[attrib][3];
238*61046927SAndroid Build Coastguard Worker }
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker return;
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_TWOSIDE: {
243*61046927SAndroid Build Coastguard Worker const unsigned first_light = state[1];
244*61046927SAndroid Build Coastguard Worker const unsigned num_lights = state[2];
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_lights; i++) {
247*61046927SAndroid Build Coastguard Worker unsigned light = first_light + i;
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker for (unsigned attrib = MAT_ATTRIB_FRONT_AMBIENT;
250*61046927SAndroid Build Coastguard Worker attrib <= MAT_ATTRIB_BACK_SPECULAR; attrib++) {
251*61046927SAndroid Build Coastguard Worker for (int chan = 0; chan < 3; chan++) {
252*61046927SAndroid Build Coastguard Worker /* We want offset to access out of bounds into the following
253*61046927SAndroid Build Coastguard Worker * Diffuse and Specular fields. This is guaranteed to work
254*61046927SAndroid Build Coastguard Worker * because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely
255*61046927SAndroid Build Coastguard Worker * on this memory layout.
256*61046927SAndroid Build Coastguard Worker */
257*61046927SAndroid Build Coastguard Worker unsigned offset = (attrib / 2) * 4 + chan;
258*61046927SAndroid Build Coastguard Worker *value++ =
259*61046927SAndroid Build Coastguard Worker (&ctx->Light.LightSource[light].Ambient[0])[offset] *
260*61046927SAndroid Build Coastguard Worker ctx->Light.Material.Attrib[attrib][chan];
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker /* [3] = material alpha */
263*61046927SAndroid Build Coastguard Worker *value++ = ctx->Light.Material.Attrib[attrib][3];
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker }
266*61046927SAndroid Build Coastguard Worker return;
267*61046927SAndroid Build Coastguard Worker }
268*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN:
269*61046927SAndroid Build Coastguard Worker {
270*61046927SAndroid Build Coastguard Worker /* state[1] is the texture unit */
271*61046927SAndroid Build Coastguard Worker const GLuint unit = (GLuint) state[1];
272*61046927SAndroid Build Coastguard Worker /* state[2] is the texgen attribute */
273*61046927SAndroid Build Coastguard Worker /* Assertions for the expected memory layout. */
274*61046927SAndroid Build Coastguard Worker #define MEMBER_SIZEOF(type, member) sizeof(((type *)0)->member)
275*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(MEMBER_SIZEOF(struct gl_fixedfunc_texture_unit,
276*61046927SAndroid Build Coastguard Worker EyePlane[0]) == 4 * sizeof(float));
277*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(MEMBER_SIZEOF(struct gl_fixedfunc_texture_unit,
278*61046927SAndroid Build Coastguard Worker ObjectPlane[0]) == 4 * sizeof(float));
279*61046927SAndroid Build Coastguard Worker #undef MEMBER_SIZEOF
280*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S == GEN_T - GEN_S);
281*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S == GEN_R - GEN_S);
282*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S == GEN_Q - GEN_S);
283*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(offsetof(struct gl_fixedfunc_texture_unit, ObjectPlane) -
284*61046927SAndroid Build Coastguard Worker offsetof(struct gl_fixedfunc_texture_unit, EyePlane) ==
285*61046927SAndroid Build Coastguard Worker (STATE_TEXGEN_OBJECT_S - STATE_TEXGEN_EYE_S) * 4 * sizeof(float));
286*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_TEXGEN_OBJECT_T - STATE_TEXGEN_OBJECT_S == GEN_T - GEN_S);
287*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_TEXGEN_OBJECT_R - STATE_TEXGEN_OBJECT_S == GEN_R - GEN_S);
288*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_TEXGEN_OBJECT_Q - STATE_TEXGEN_OBJECT_S == GEN_Q - GEN_S);
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker const float *attr = (float*)ctx->Texture.FixedFuncUnit[unit].EyePlane +
291*61046927SAndroid Build Coastguard Worker (state[2] - STATE_TEXGEN_EYE_S) * 4;
292*61046927SAndroid Build Coastguard Worker COPY_4V(value, attr);
293*61046927SAndroid Build Coastguard Worker return;
294*61046927SAndroid Build Coastguard Worker }
295*61046927SAndroid Build Coastguard Worker case STATE_TEXENV_COLOR:
296*61046927SAndroid Build Coastguard Worker {
297*61046927SAndroid Build Coastguard Worker /* state[1] is the texture unit */
298*61046927SAndroid Build Coastguard Worker const GLuint unit = (GLuint) state[1];
299*61046927SAndroid Build Coastguard Worker if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
300*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Texture.FixedFuncUnit[unit].EnvColor);
301*61046927SAndroid Build Coastguard Worker else
302*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Texture.FixedFuncUnit[unit].EnvColorUnclamped);
303*61046927SAndroid Build Coastguard Worker }
304*61046927SAndroid Build Coastguard Worker return;
305*61046927SAndroid Build Coastguard Worker case STATE_FOG_COLOR:
306*61046927SAndroid Build Coastguard Worker if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
307*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Fog.Color);
308*61046927SAndroid Build Coastguard Worker else
309*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Fog.ColorUnclamped);
310*61046927SAndroid Build Coastguard Worker return;
311*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS: {
312*61046927SAndroid Build Coastguard Worker float scale = 1.0f / (ctx->Fog.End - ctx->Fog.Start);
313*61046927SAndroid Build Coastguard Worker /* Pass +-FLT_MAX/2 to the shader instead of +-Inf because Infs have
314*61046927SAndroid Build Coastguard Worker * undefined behavior without GLSL 4.10 or GL_ARB_shader_precision
315*61046927SAndroid Build Coastguard Worker * enabled. Infs also have undefined behavior with Shader Model 3.
316*61046927SAndroid Build Coastguard Worker *
317*61046927SAndroid Build Coastguard Worker * The division by 2 makes it less likely that ALU ops will generate
318*61046927SAndroid Build Coastguard Worker * Inf.
319*61046927SAndroid Build Coastguard Worker */
320*61046927SAndroid Build Coastguard Worker scale = CLAMP(scale, FLT_MIN / 2, FLT_MAX / 2);
321*61046927SAndroid Build Coastguard Worker value[0] = ctx->Fog.Density;
322*61046927SAndroid Build Coastguard Worker value[1] = ctx->Fog.Start;
323*61046927SAndroid Build Coastguard Worker value[2] = ctx->Fog.End;
324*61046927SAndroid Build Coastguard Worker value[3] = scale;
325*61046927SAndroid Build Coastguard Worker return;
326*61046927SAndroid Build Coastguard Worker }
327*61046927SAndroid Build Coastguard Worker case STATE_CLIPPLANE:
328*61046927SAndroid Build Coastguard Worker {
329*61046927SAndroid Build Coastguard Worker const GLuint plane = (GLuint) state[1];
330*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
331*61046927SAndroid Build Coastguard Worker }
332*61046927SAndroid Build Coastguard Worker return;
333*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE:
334*61046927SAndroid Build Coastguard Worker value[0] = ctx->Point.Size;
335*61046927SAndroid Build Coastguard Worker value[1] = ctx->Point.MinSize;
336*61046927SAndroid Build Coastguard Worker value[2] = ctx->Point.MaxSize;
337*61046927SAndroid Build Coastguard Worker value[3] = ctx->Point.Threshold;
338*61046927SAndroid Build Coastguard Worker return;
339*61046927SAndroid Build Coastguard Worker case STATE_POINT_ATTENUATION:
340*61046927SAndroid Build Coastguard Worker value[0] = ctx->Point.Params[0];
341*61046927SAndroid Build Coastguard Worker value[1] = ctx->Point.Params[1];
342*61046927SAndroid Build Coastguard Worker value[2] = ctx->Point.Params[2];
343*61046927SAndroid Build Coastguard Worker value[3] = 1.0F;
344*61046927SAndroid Build Coastguard Worker return;
345*61046927SAndroid Build Coastguard Worker /* state[0] = modelview, projection, texture, etc. */
346*61046927SAndroid Build Coastguard Worker /* state[1] = which texture matrix or program matrix */
347*61046927SAndroid Build Coastguard Worker /* state[2] = first row to fetch */
348*61046927SAndroid Build Coastguard Worker /* state[3] = last row to fetch */
349*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX: {
350*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top;
351*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->m, state[2], state[3]);
352*61046927SAndroid Build Coastguard Worker return;
353*61046927SAndroid Build Coastguard Worker }
354*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVERSE: {
355*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top;
356*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->inv, state[2], state[3]);
357*61046927SAndroid Build Coastguard Worker return;
358*61046927SAndroid Build Coastguard Worker }
359*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_TRANSPOSE: {
360*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top;
361*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->m, state[2], state[3]);
362*61046927SAndroid Build Coastguard Worker return;
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVTRANS: {
365*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ModelviewMatrixStack.Top;
366*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->inv, state[2], state[3]);
367*61046927SAndroid Build Coastguard Worker return;
368*61046927SAndroid Build Coastguard Worker }
369*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX: {
370*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ProjectionMatrixStack.Top;
371*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->m, state[2], state[3]);
372*61046927SAndroid Build Coastguard Worker return;
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVERSE: {
375*61046927SAndroid Build Coastguard Worker GLmatrix *matrix = ctx->ProjectionMatrixStack.Top;
376*61046927SAndroid Build Coastguard Worker _math_matrix_analyse(matrix); /* make sure the inverse is up to date */
377*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->inv, state[2], state[3]);
378*61046927SAndroid Build Coastguard Worker return;
379*61046927SAndroid Build Coastguard Worker }
380*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_TRANSPOSE: {
381*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ProjectionMatrixStack.Top;
382*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->m, state[2], state[3]);
383*61046927SAndroid Build Coastguard Worker return;
384*61046927SAndroid Build Coastguard Worker }
385*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVTRANS: {
386*61046927SAndroid Build Coastguard Worker GLmatrix *matrix = ctx->ProjectionMatrixStack.Top;
387*61046927SAndroid Build Coastguard Worker _math_matrix_analyse(matrix); /* make sure the inverse is up to date */
388*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->inv, state[2], state[3]);
389*61046927SAndroid Build Coastguard Worker return;
390*61046927SAndroid Build Coastguard Worker }
391*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX: {
392*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = &ctx->_ModelProjectMatrix;
393*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->m, state[2], state[3]);
394*61046927SAndroid Build Coastguard Worker return;
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVERSE: {
397*61046927SAndroid Build Coastguard Worker GLmatrix *matrix = &ctx->_ModelProjectMatrix;
398*61046927SAndroid Build Coastguard Worker _math_matrix_analyse(matrix); /* make sure the inverse is up to date */
399*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->inv, state[2], state[3]);
400*61046927SAndroid Build Coastguard Worker return;
401*61046927SAndroid Build Coastguard Worker }
402*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_TRANSPOSE: {
403*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = &ctx->_ModelProjectMatrix;
404*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->m, state[2], state[3]);
405*61046927SAndroid Build Coastguard Worker return;
406*61046927SAndroid Build Coastguard Worker }
407*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVTRANS: {
408*61046927SAndroid Build Coastguard Worker GLmatrix *matrix = &ctx->_ModelProjectMatrix;
409*61046927SAndroid Build Coastguard Worker _math_matrix_analyse(matrix); /* make sure the inverse is up to date */
410*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->inv, state[2], state[3]);
411*61046927SAndroid Build Coastguard Worker return;
412*61046927SAndroid Build Coastguard Worker }
413*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX: {
414*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
415*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->TextureMatrixStack));
416*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top;
417*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->m, state[2], state[3]);
418*61046927SAndroid Build Coastguard Worker return;
419*61046927SAndroid Build Coastguard Worker }
420*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVERSE: {
421*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
422*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->TextureMatrixStack));
423*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top;
424*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->inv, state[2], state[3]);
425*61046927SAndroid Build Coastguard Worker return;
426*61046927SAndroid Build Coastguard Worker }
427*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_TRANSPOSE: {
428*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
429*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->TextureMatrixStack));
430*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top;
431*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->m, state[2], state[3]);
432*61046927SAndroid Build Coastguard Worker return;
433*61046927SAndroid Build Coastguard Worker }
434*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVTRANS: {
435*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
436*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->TextureMatrixStack));
437*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->TextureMatrixStack[index].Top;
438*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->inv, state[2], state[3]);
439*61046927SAndroid Build Coastguard Worker return;
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX: {
442*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
443*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack));
444*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top;
445*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->m, state[2], state[3]);
446*61046927SAndroid Build Coastguard Worker return;
447*61046927SAndroid Build Coastguard Worker }
448*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVERSE: {
449*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
450*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack));
451*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top;
452*61046927SAndroid Build Coastguard Worker _math_matrix_analyse((GLmatrix*)matrix); /* Be sure inverse is up to date: */
453*61046927SAndroid Build Coastguard Worker copy_matrix(value, matrix->inv, state[2], state[3]);
454*61046927SAndroid Build Coastguard Worker return;
455*61046927SAndroid Build Coastguard Worker }
456*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_TRANSPOSE: {
457*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
458*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack));
459*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top;
460*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->m, state[2], state[3]);
461*61046927SAndroid Build Coastguard Worker return;
462*61046927SAndroid Build Coastguard Worker }
463*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVTRANS: {
464*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
465*61046927SAndroid Build Coastguard Worker assert(index < ARRAY_SIZE(ctx->ProgramMatrixStack));
466*61046927SAndroid Build Coastguard Worker const GLmatrix *matrix = ctx->ProgramMatrixStack[index].Top;
467*61046927SAndroid Build Coastguard Worker _math_matrix_analyse((GLmatrix*)matrix); /* Be sure inverse is up to date: */
468*61046927SAndroid Build Coastguard Worker copy_matrix_transposed(value, matrix->inv, state[2], state[3]);
469*61046927SAndroid Build Coastguard Worker return;
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker case STATE_NUM_SAMPLES:
472*61046927SAndroid Build Coastguard Worker val[0].i = MAX2(1, _mesa_geometric_samples(ctx->DrawBuffer));
473*61046927SAndroid Build Coastguard Worker return;
474*61046927SAndroid Build Coastguard Worker case STATE_DEPTH_RANGE:
475*61046927SAndroid Build Coastguard Worker value[0] = ctx->ViewportArray[0].Near; /* near */
476*61046927SAndroid Build Coastguard Worker value[1] = ctx->ViewportArray[0].Far; /* far */
477*61046927SAndroid Build Coastguard Worker value[2] = ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near; /* far - near */
478*61046927SAndroid Build Coastguard Worker value[3] = 1.0;
479*61046927SAndroid Build Coastguard Worker return;
480*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV: {
481*61046927SAndroid Build Coastguard Worker const int idx = (int) state[1];
482*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
483*61046927SAndroid Build Coastguard Worker return;
484*61046927SAndroid Build Coastguard Worker }
485*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV_ARRAY: {
486*61046927SAndroid Build Coastguard Worker const unsigned idx = state[1];
487*61046927SAndroid Build Coastguard Worker const unsigned bytes = state[2] * 16;
488*61046927SAndroid Build Coastguard Worker memcpy(value, ctx->FragmentProgram.Parameters[idx], bytes);
489*61046927SAndroid Build Coastguard Worker return;
490*61046927SAndroid Build Coastguard Worker }
491*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL: {
492*61046927SAndroid Build Coastguard Worker float (*params)[4] = ctx->FragmentProgram.Current->arb.LocalParams;
493*61046927SAndroid Build Coastguard Worker if (unlikely(!params)) {
494*61046927SAndroid Build Coastguard Worker /* Local parameters haven't been allocated yet.
495*61046927SAndroid Build Coastguard Worker * ARB_fragment_program says that local parameters are
496*61046927SAndroid Build Coastguard Worker * "initially set to (0,0,0,0)." Return that.
497*61046927SAndroid Build Coastguard Worker */
498*61046927SAndroid Build Coastguard Worker memset(value, 0, sizeof(float) * 4);
499*61046927SAndroid Build Coastguard Worker return;
500*61046927SAndroid Build Coastguard Worker }
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker const int idx = (int) state[1];
503*61046927SAndroid Build Coastguard Worker COPY_4V(value, params[idx]);
504*61046927SAndroid Build Coastguard Worker return;
505*61046927SAndroid Build Coastguard Worker }
506*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY: {
507*61046927SAndroid Build Coastguard Worker const unsigned idx = state[1];
508*61046927SAndroid Build Coastguard Worker const unsigned bytes = state[2] * 16;
509*61046927SAndroid Build Coastguard Worker float (*params)[4] = ctx->FragmentProgram.Current->arb.LocalParams;
510*61046927SAndroid Build Coastguard Worker if (!params) {
511*61046927SAndroid Build Coastguard Worker /* Local parameters haven't been allocated yet.
512*61046927SAndroid Build Coastguard Worker * ARB_fragment_program says that local parameters are
513*61046927SAndroid Build Coastguard Worker * "initially set to (0,0,0,0)." Return that.
514*61046927SAndroid Build Coastguard Worker */
515*61046927SAndroid Build Coastguard Worker memset(value, 0, bytes);
516*61046927SAndroid Build Coastguard Worker return;
517*61046927SAndroid Build Coastguard Worker }
518*61046927SAndroid Build Coastguard Worker memcpy(value, params[idx], bytes);
519*61046927SAndroid Build Coastguard Worker return;
520*61046927SAndroid Build Coastguard Worker }
521*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV: {
522*61046927SAndroid Build Coastguard Worker const int idx = (int) state[1];
523*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
524*61046927SAndroid Build Coastguard Worker return;
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV_ARRAY: {
527*61046927SAndroid Build Coastguard Worker const unsigned idx = state[1];
528*61046927SAndroid Build Coastguard Worker const unsigned bytes = state[2] * 16;
529*61046927SAndroid Build Coastguard Worker memcpy(value, ctx->VertexProgram.Parameters[idx], bytes);
530*61046927SAndroid Build Coastguard Worker return;
531*61046927SAndroid Build Coastguard Worker }
532*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL: {
533*61046927SAndroid Build Coastguard Worker float (*params)[4] = ctx->VertexProgram.Current->arb.LocalParams;
534*61046927SAndroid Build Coastguard Worker if (unlikely(!params)) {
535*61046927SAndroid Build Coastguard Worker /* Local parameters haven't been allocated yet.
536*61046927SAndroid Build Coastguard Worker * ARB_vertex_program says that local parameters are
537*61046927SAndroid Build Coastguard Worker * "initially set to (0,0,0,0)." Return that.
538*61046927SAndroid Build Coastguard Worker */
539*61046927SAndroid Build Coastguard Worker memset(value, 0, sizeof(float) * 4);
540*61046927SAndroid Build Coastguard Worker return;
541*61046927SAndroid Build Coastguard Worker }
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker const int idx = (int) state[1];
544*61046927SAndroid Build Coastguard Worker COPY_4V(value, params[idx]);
545*61046927SAndroid Build Coastguard Worker return;
546*61046927SAndroid Build Coastguard Worker }
547*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL_ARRAY: {
548*61046927SAndroid Build Coastguard Worker const unsigned idx = state[1];
549*61046927SAndroid Build Coastguard Worker const unsigned bytes = state[2] * 16;
550*61046927SAndroid Build Coastguard Worker float (*params)[4] = ctx->VertexProgram.Current->arb.LocalParams;
551*61046927SAndroid Build Coastguard Worker if (!params) {
552*61046927SAndroid Build Coastguard Worker /* Local parameters haven't been allocated yet.
553*61046927SAndroid Build Coastguard Worker * ARB_vertex_program says that local parameters are
554*61046927SAndroid Build Coastguard Worker * "initially set to (0,0,0,0)." Return that.
555*61046927SAndroid Build Coastguard Worker */
556*61046927SAndroid Build Coastguard Worker memset(value, 0, bytes);
557*61046927SAndroid Build Coastguard Worker return;
558*61046927SAndroid Build Coastguard Worker }
559*61046927SAndroid Build Coastguard Worker memcpy(value, params[idx], bytes);
560*61046927SAndroid Build Coastguard Worker return;
561*61046927SAndroid Build Coastguard Worker }
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE_EYESPACE:
564*61046927SAndroid Build Coastguard Worker ASSIGN_4V(value, ctx->_ModelViewInvScaleEyespace, 0, 0, 1);
565*61046927SAndroid Build Coastguard Worker return;
566*61046927SAndroid Build Coastguard Worker
567*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB:
568*61046927SAndroid Build Coastguard Worker {
569*61046927SAndroid Build Coastguard Worker const GLuint idx = (GLuint) state[1];
570*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Current.Attrib[idx]);
571*61046927SAndroid Build Coastguard Worker }
572*61046927SAndroid Build Coastguard Worker return;
573*61046927SAndroid Build Coastguard Worker
574*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
575*61046927SAndroid Build Coastguard Worker {
576*61046927SAndroid Build Coastguard Worker const GLuint idx = (GLuint) state[1];
577*61046927SAndroid Build Coastguard Worker if(ctx->Light._ClampVertexColor &&
578*61046927SAndroid Build Coastguard Worker (idx == VERT_ATTRIB_COLOR0 ||
579*61046927SAndroid Build Coastguard Worker idx == VERT_ATTRIB_COLOR1)) {
580*61046927SAndroid Build Coastguard Worker value[0] = SATURATE(ctx->Current.Attrib[idx][0]);
581*61046927SAndroid Build Coastguard Worker value[1] = SATURATE(ctx->Current.Attrib[idx][1]);
582*61046927SAndroid Build Coastguard Worker value[2] = SATURATE(ctx->Current.Attrib[idx][2]);
583*61046927SAndroid Build Coastguard Worker value[3] = SATURATE(ctx->Current.Attrib[idx][3]);
584*61046927SAndroid Build Coastguard Worker }
585*61046927SAndroid Build Coastguard Worker else
586*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Current.Attrib[idx]);
587*61046927SAndroid Build Coastguard Worker }
588*61046927SAndroid Build Coastguard Worker return;
589*61046927SAndroid Build Coastguard Worker
590*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE:
591*61046927SAndroid Build Coastguard Worker ASSIGN_4V(value,
592*61046927SAndroid Build Coastguard Worker ctx->_ModelViewInvScale,
593*61046927SAndroid Build Coastguard Worker ctx->_ModelViewInvScale,
594*61046927SAndroid Build Coastguard Worker ctx->_ModelViewInvScale,
595*61046927SAndroid Build Coastguard Worker 1);
596*61046927SAndroid Build Coastguard Worker return;
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS_OPTIMIZED: {
599*61046927SAndroid Build Coastguard Worker /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog)
600*61046927SAndroid Build Coastguard Worker * might be more expensive than EX2 on some hw, plus it needs
601*61046927SAndroid Build Coastguard Worker * another constant (e) anyway. Linear fog can now be done with a
602*61046927SAndroid Build Coastguard Worker * single MAD.
603*61046927SAndroid Build Coastguard Worker * linear: fogcoord * -1/(end-start) + end/(end-start)
604*61046927SAndroid Build Coastguard Worker * exp: 2^-(density/ln(2) * fogcoord)
605*61046927SAndroid Build Coastguard Worker * exp2: 2^-((density/(sqrt(ln(2))) * fogcoord)^2)
606*61046927SAndroid Build Coastguard Worker */
607*61046927SAndroid Build Coastguard Worker float val = (ctx->Fog.End == ctx->Fog.Start)
608*61046927SAndroid Build Coastguard Worker ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start));
609*61046927SAndroid Build Coastguard Worker value[0] = val;
610*61046927SAndroid Build Coastguard Worker value[1] = ctx->Fog.End * -val;
611*61046927SAndroid Build Coastguard Worker value[2] = (GLfloat)(ctx->Fog.Density * M_LOG2E); /* M_LOG2E == 1/ln(2) */
612*61046927SAndroid Build Coastguard Worker value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2);
613*61046927SAndroid Build Coastguard Worker return;
614*61046927SAndroid Build Coastguard Worker }
615*61046927SAndroid Build Coastguard Worker
616*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE_CLAMPED:
617*61046927SAndroid Build Coastguard Worker {
618*61046927SAndroid Build Coastguard Worker /* this includes implementation dependent limits, to avoid
619*61046927SAndroid Build Coastguard Worker * another potentially necessary clamp.
620*61046927SAndroid Build Coastguard Worker * Note: for sprites, point smooth (point AA) is ignored
621*61046927SAndroid Build Coastguard Worker * and we'll clamp to MinPointSizeAA and MaxPointSize, because we
622*61046927SAndroid Build Coastguard Worker * expect drivers will want to say their minimum for AA size is 0.0
623*61046927SAndroid Build Coastguard Worker * but for non-AA it's 1.0 (because normal points with size below 1.0
624*61046927SAndroid Build Coastguard Worker * need to get rounded up to 1.0, hence never disappear). GL does
625*61046927SAndroid Build Coastguard Worker * not specify max clamp size for sprites, other than it needs to be
626*61046927SAndroid Build Coastguard Worker * at least as large as max AA size, hence use non-AA size there.
627*61046927SAndroid Build Coastguard Worker */
628*61046927SAndroid Build Coastguard Worker GLfloat minImplSize;
629*61046927SAndroid Build Coastguard Worker GLfloat maxImplSize;
630*61046927SAndroid Build Coastguard Worker if (ctx->Point.PointSprite) {
631*61046927SAndroid Build Coastguard Worker minImplSize = ctx->Const.MinPointSizeAA;
632*61046927SAndroid Build Coastguard Worker maxImplSize = ctx->Const.MaxPointSize;
633*61046927SAndroid Build Coastguard Worker }
634*61046927SAndroid Build Coastguard Worker else if (ctx->Point.SmoothFlag || _mesa_is_multisample_enabled(ctx)) {
635*61046927SAndroid Build Coastguard Worker minImplSize = ctx->Const.MinPointSizeAA;
636*61046927SAndroid Build Coastguard Worker maxImplSize = ctx->Const.MaxPointSizeAA;
637*61046927SAndroid Build Coastguard Worker }
638*61046927SAndroid Build Coastguard Worker else {
639*61046927SAndroid Build Coastguard Worker minImplSize = ctx->Const.MinPointSize;
640*61046927SAndroid Build Coastguard Worker maxImplSize = ctx->Const.MaxPointSize;
641*61046927SAndroid Build Coastguard Worker }
642*61046927SAndroid Build Coastguard Worker value[0] = ctx->Point.Size;
643*61046927SAndroid Build Coastguard Worker value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize;
644*61046927SAndroid Build Coastguard Worker value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize;
645*61046927SAndroid Build Coastguard Worker value[3] = ctx->Point.Threshold;
646*61046927SAndroid Build Coastguard Worker }
647*61046927SAndroid Build Coastguard Worker return;
648*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_SPOT_DIR_NORMALIZED:
649*61046927SAndroid Build Coastguard Worker {
650*61046927SAndroid Build Coastguard Worker /* here, state[1] is the light number */
651*61046927SAndroid Build Coastguard Worker /* pre-normalize spot dir */
652*61046927SAndroid Build Coastguard Worker const GLuint ln = (GLuint) state[1];
653*61046927SAndroid Build Coastguard Worker COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection);
654*61046927SAndroid Build Coastguard Worker value[3] = ctx->Light.LightSource[ln]._CosCutoff;
655*61046927SAndroid Build Coastguard Worker }
656*61046927SAndroid Build Coastguard Worker return;
657*61046927SAndroid Build Coastguard Worker
658*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION:
659*61046927SAndroid Build Coastguard Worker {
660*61046927SAndroid Build Coastguard Worker const GLuint ln = (GLuint) state[1];
661*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Light.Light[ln]._Position);
662*61046927SAndroid Build Coastguard Worker }
663*61046927SAndroid Build Coastguard Worker return;
664*61046927SAndroid Build Coastguard Worker
665*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_ARRAY: {
666*61046927SAndroid Build Coastguard Worker const unsigned first = state[1];
667*61046927SAndroid Build Coastguard Worker const unsigned num_lights = state[2];
668*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_lights; i++) {
669*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Light.Light[first + i]._Position);
670*61046927SAndroid Build Coastguard Worker value += 4;
671*61046927SAndroid Build Coastguard Worker }
672*61046927SAndroid Build Coastguard Worker return;
673*61046927SAndroid Build Coastguard Worker }
674*61046927SAndroid Build Coastguard Worker
675*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED:
676*61046927SAndroid Build Coastguard Worker {
677*61046927SAndroid Build Coastguard Worker const GLuint ln = (GLuint) state[1];
678*61046927SAndroid Build Coastguard Worker float p[4];
679*61046927SAndroid Build Coastguard Worker COPY_4V(p, ctx->Light.Light[ln]._Position);
680*61046927SAndroid Build Coastguard Worker NORMALIZE_3FV(p);
681*61046927SAndroid Build Coastguard Worker COPY_4V(value, p);
682*61046927SAndroid Build Coastguard Worker }
683*61046927SAndroid Build Coastguard Worker return;
684*61046927SAndroid Build Coastguard Worker
685*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED_ARRAY: {
686*61046927SAndroid Build Coastguard Worker const unsigned first = state[1];
687*61046927SAndroid Build Coastguard Worker const unsigned num_lights = state[2];
688*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_lights; i++) {
689*61046927SAndroid Build Coastguard Worker float p[4];
690*61046927SAndroid Build Coastguard Worker COPY_4V(p, ctx->Light.Light[first + i]._Position);
691*61046927SAndroid Build Coastguard Worker NORMALIZE_3FV(p);
692*61046927SAndroid Build Coastguard Worker COPY_4V(value, p);
693*61046927SAndroid Build Coastguard Worker value += 4;
694*61046927SAndroid Build Coastguard Worker }
695*61046927SAndroid Build Coastguard Worker return;
696*61046927SAndroid Build Coastguard Worker }
697*61046927SAndroid Build Coastguard Worker
698*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_HALF_VECTOR:
699*61046927SAndroid Build Coastguard Worker {
700*61046927SAndroid Build Coastguard Worker const GLuint ln = (GLuint) state[1];
701*61046927SAndroid Build Coastguard Worker GLfloat p[3];
702*61046927SAndroid Build Coastguard Worker /* Compute infinite half angle vector:
703*61046927SAndroid Build Coastguard Worker * halfVector = normalize(normalize(lightPos) + (0, 0, 1))
704*61046927SAndroid Build Coastguard Worker * light.EyePosition.w should be 0 for infinite lights.
705*61046927SAndroid Build Coastguard Worker */
706*61046927SAndroid Build Coastguard Worker COPY_3V(p, ctx->Light.Light[ln]._Position);
707*61046927SAndroid Build Coastguard Worker NORMALIZE_3FV(p);
708*61046927SAndroid Build Coastguard Worker ADD_3V(p, p, ctx->_EyeZDir);
709*61046927SAndroid Build Coastguard Worker NORMALIZE_3FV(p);
710*61046927SAndroid Build Coastguard Worker COPY_3V(value, p);
711*61046927SAndroid Build Coastguard Worker value[3] = 1.0;
712*61046927SAndroid Build Coastguard Worker }
713*61046927SAndroid Build Coastguard Worker return;
714*61046927SAndroid Build Coastguard Worker
715*61046927SAndroid Build Coastguard Worker case STATE_PT_SCALE:
716*61046927SAndroid Build Coastguard Worker value[0] = ctx->Pixel.RedScale;
717*61046927SAndroid Build Coastguard Worker value[1] = ctx->Pixel.GreenScale;
718*61046927SAndroid Build Coastguard Worker value[2] = ctx->Pixel.BlueScale;
719*61046927SAndroid Build Coastguard Worker value[3] = ctx->Pixel.AlphaScale;
720*61046927SAndroid Build Coastguard Worker return;
721*61046927SAndroid Build Coastguard Worker
722*61046927SAndroid Build Coastguard Worker case STATE_PT_BIAS:
723*61046927SAndroid Build Coastguard Worker value[0] = ctx->Pixel.RedBias;
724*61046927SAndroid Build Coastguard Worker value[1] = ctx->Pixel.GreenBias;
725*61046927SAndroid Build Coastguard Worker value[2] = ctx->Pixel.BlueBias;
726*61046927SAndroid Build Coastguard Worker value[3] = ctx->Pixel.AlphaBias;
727*61046927SAndroid Build Coastguard Worker return;
728*61046927SAndroid Build Coastguard Worker
729*61046927SAndroid Build Coastguard Worker case STATE_FB_SIZE:
730*61046927SAndroid Build Coastguard Worker value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1);
731*61046927SAndroid Build Coastguard Worker value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
732*61046927SAndroid Build Coastguard Worker value[2] = 0.0F;
733*61046927SAndroid Build Coastguard Worker value[3] = 0.0F;
734*61046927SAndroid Build Coastguard Worker return;
735*61046927SAndroid Build Coastguard Worker
736*61046927SAndroid Build Coastguard Worker case STATE_FB_WPOS_Y_TRANSFORM:
737*61046927SAndroid Build Coastguard Worker /* A driver may negate this conditional by using ZW swizzle
738*61046927SAndroid Build Coastguard Worker * instead of XY (based on e.g. some other state). */
739*61046927SAndroid Build Coastguard Worker if (!ctx->DrawBuffer->FlipY) {
740*61046927SAndroid Build Coastguard Worker /* Identity (XY) followed by flipping Y upside down (ZW). */
741*61046927SAndroid Build Coastguard Worker value[0] = 1.0F;
742*61046927SAndroid Build Coastguard Worker value[1] = 0.0F;
743*61046927SAndroid Build Coastguard Worker value[2] = -1.0F;
744*61046927SAndroid Build Coastguard Worker value[3] = _mesa_geometric_height(ctx->DrawBuffer);
745*61046927SAndroid Build Coastguard Worker } else {
746*61046927SAndroid Build Coastguard Worker /* Flipping Y upside down (XY) followed by identity (ZW). */
747*61046927SAndroid Build Coastguard Worker value[0] = -1.0F;
748*61046927SAndroid Build Coastguard Worker value[1] = _mesa_geometric_height(ctx->DrawBuffer);
749*61046927SAndroid Build Coastguard Worker value[2] = 1.0F;
750*61046927SAndroid Build Coastguard Worker value[3] = 0.0F;
751*61046927SAndroid Build Coastguard Worker }
752*61046927SAndroid Build Coastguard Worker return;
753*61046927SAndroid Build Coastguard Worker
754*61046927SAndroid Build Coastguard Worker case STATE_FB_PNTC_Y_TRANSFORM:
755*61046927SAndroid Build Coastguard Worker {
756*61046927SAndroid Build Coastguard Worker bool flip_y = (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) ^
757*61046927SAndroid Build Coastguard Worker (ctx->DrawBuffer->FlipY);
758*61046927SAndroid Build Coastguard Worker
759*61046927SAndroid Build Coastguard Worker value[0] = flip_y ? -1.0F : 1.0F;
760*61046927SAndroid Build Coastguard Worker value[1] = flip_y ? 1.0F : 0.0F;
761*61046927SAndroid Build Coastguard Worker value[2] = 0.0F;
762*61046927SAndroid Build Coastguard Worker value[3] = 0.0F;
763*61046927SAndroid Build Coastguard Worker }
764*61046927SAndroid Build Coastguard Worker return;
765*61046927SAndroid Build Coastguard Worker
766*61046927SAndroid Build Coastguard Worker case STATE_TCS_PATCH_VERTICES_IN:
767*61046927SAndroid Build Coastguard Worker val[0].i = ctx->TessCtrlProgram.patch_vertices;
768*61046927SAndroid Build Coastguard Worker return;
769*61046927SAndroid Build Coastguard Worker
770*61046927SAndroid Build Coastguard Worker case STATE_TES_PATCH_VERTICES_IN:
771*61046927SAndroid Build Coastguard Worker if (ctx->TessCtrlProgram._Current)
772*61046927SAndroid Build Coastguard Worker val[0].i = ctx->TessCtrlProgram._Current->info.tess.tcs_vertices_out;
773*61046927SAndroid Build Coastguard Worker else
774*61046927SAndroid Build Coastguard Worker val[0].i = ctx->TessCtrlProgram.patch_vertices;
775*61046927SAndroid Build Coastguard Worker return;
776*61046927SAndroid Build Coastguard Worker
777*61046927SAndroid Build Coastguard Worker case STATE_ADVANCED_BLENDING_MODE:
778*61046927SAndroid Build Coastguard Worker val[0].i = _mesa_get_advanced_blend_sh_constant(
779*61046927SAndroid Build Coastguard Worker ctx->Color.BlendEnabled, ctx->Color._AdvancedBlendMode);
780*61046927SAndroid Build Coastguard Worker return;
781*61046927SAndroid Build Coastguard Worker
782*61046927SAndroid Build Coastguard Worker case STATE_ALPHA_REF:
783*61046927SAndroid Build Coastguard Worker value[0] = ctx->Color.AlphaRefUnclamped;
784*61046927SAndroid Build Coastguard Worker return;
785*61046927SAndroid Build Coastguard Worker
786*61046927SAndroid Build Coastguard Worker case STATE_CLIP_INTERNAL:
787*61046927SAndroid Build Coastguard Worker {
788*61046927SAndroid Build Coastguard Worker const GLuint plane = (GLuint) state[1];
789*61046927SAndroid Build Coastguard Worker COPY_4V(value, ctx->Transform._ClipUserPlane[plane]);
790*61046927SAndroid Build Coastguard Worker }
791*61046927SAndroid Build Coastguard Worker return;
792*61046927SAndroid Build Coastguard Worker
793*61046927SAndroid Build Coastguard Worker case STATE_ATOMIC_COUNTER_OFFSET:
794*61046927SAndroid Build Coastguard Worker {
795*61046927SAndroid Build Coastguard Worker const GLuint counter = (GLuint) state[1];
796*61046927SAndroid Build Coastguard Worker val[0].i = ctx->AtomicBufferBindings[counter].Offset % ctx->Const.ShaderStorageBufferOffsetAlignment;
797*61046927SAndroid Build Coastguard Worker }
798*61046927SAndroid Build Coastguard Worker return;
799*61046927SAndroid Build Coastguard Worker }
800*61046927SAndroid Build Coastguard Worker }
801*61046927SAndroid Build Coastguard Worker
802*61046927SAndroid Build Coastguard Worker unsigned
_mesa_program_state_value_size(const gl_state_index16 state[STATE_LENGTH])803*61046927SAndroid Build Coastguard Worker _mesa_program_state_value_size(const gl_state_index16 state[STATE_LENGTH])
804*61046927SAndroid Build Coastguard Worker {
805*61046927SAndroid Build Coastguard Worker if (state[0] == STATE_LIGHT && state[2] == STATE_SPOT_CUTOFF)
806*61046927SAndroid Build Coastguard Worker return 1;
807*61046927SAndroid Build Coastguard Worker
808*61046927SAndroid Build Coastguard Worker /* Everything else is packed into vec4s */
809*61046927SAndroid Build Coastguard Worker return 4;
810*61046927SAndroid Build Coastguard Worker }
811*61046927SAndroid Build Coastguard Worker
812*61046927SAndroid Build Coastguard Worker /**
813*61046927SAndroid Build Coastguard Worker * Return a bitmask of the Mesa state flags (_NEW_* values) which would
814*61046927SAndroid Build Coastguard Worker * indicate that the given context state may have changed.
815*61046927SAndroid Build Coastguard Worker * The bitmask is used during validation to determine if we need to update
816*61046927SAndroid Build Coastguard Worker * vertex/fragment program parameters (like "state.material.color") when
817*61046927SAndroid Build Coastguard Worker * some GL state has changed.
818*61046927SAndroid Build Coastguard Worker */
819*61046927SAndroid Build Coastguard Worker GLbitfield
_mesa_program_state_flags(const gl_state_index16 state[STATE_LENGTH])820*61046927SAndroid Build Coastguard Worker _mesa_program_state_flags(const gl_state_index16 state[STATE_LENGTH])
821*61046927SAndroid Build Coastguard Worker {
822*61046927SAndroid Build Coastguard Worker switch (state[0]) {
823*61046927SAndroid Build Coastguard Worker case STATE_MATERIAL:
824*61046927SAndroid Build Coastguard Worker return _NEW_MATERIAL;
825*61046927SAndroid Build Coastguard Worker
826*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD:
827*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_FRONT:
828*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_BACK:
829*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_TWOSIDE:
830*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_SCENECOLOR:
831*61046927SAndroid Build Coastguard Worker return _NEW_LIGHT_CONSTANTS | _NEW_MATERIAL;
832*61046927SAndroid Build Coastguard Worker
833*61046927SAndroid Build Coastguard Worker case STATE_LIGHT:
834*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ARRAY:
835*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ATTENUATION_ARRAY:
836*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_AMBIENT:
837*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_SPOT_DIR_NORMALIZED:
838*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION:
839*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_ARRAY:
840*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED:
841*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED_ARRAY:
842*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_HALF_VECTOR:
843*61046927SAndroid Build Coastguard Worker return _NEW_LIGHT_CONSTANTS;
844*61046927SAndroid Build Coastguard Worker
845*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN:
846*61046927SAndroid Build Coastguard Worker return _NEW_TEXTURE_STATE;
847*61046927SAndroid Build Coastguard Worker case STATE_TEXENV_COLOR:
848*61046927SAndroid Build Coastguard Worker return _NEW_TEXTURE_STATE | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
849*61046927SAndroid Build Coastguard Worker
850*61046927SAndroid Build Coastguard Worker case STATE_FOG_COLOR:
851*61046927SAndroid Build Coastguard Worker return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
852*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS:
853*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS_OPTIMIZED:
854*61046927SAndroid Build Coastguard Worker return _NEW_FOG;
855*61046927SAndroid Build Coastguard Worker
856*61046927SAndroid Build Coastguard Worker case STATE_CLIPPLANE:
857*61046927SAndroid Build Coastguard Worker return _NEW_TRANSFORM;
858*61046927SAndroid Build Coastguard Worker
859*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE:
860*61046927SAndroid Build Coastguard Worker case STATE_POINT_ATTENUATION:
861*61046927SAndroid Build Coastguard Worker return _NEW_POINT;
862*61046927SAndroid Build Coastguard Worker
863*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX:
864*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVERSE:
865*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_TRANSPOSE:
866*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVTRANS:
867*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE_EYESPACE:
868*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE:
869*61046927SAndroid Build Coastguard Worker return _NEW_MODELVIEW;
870*61046927SAndroid Build Coastguard Worker
871*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX:
872*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVERSE:
873*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_TRANSPOSE:
874*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVTRANS:
875*61046927SAndroid Build Coastguard Worker return _NEW_PROJECTION;
876*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX:
877*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVERSE:
878*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_TRANSPOSE:
879*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVTRANS:
880*61046927SAndroid Build Coastguard Worker return _NEW_MODELVIEW | _NEW_PROJECTION;
881*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX:
882*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVERSE:
883*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_TRANSPOSE:
884*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVTRANS:
885*61046927SAndroid Build Coastguard Worker return _NEW_TEXTURE_MATRIX;
886*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX:
887*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVERSE:
888*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_TRANSPOSE:
889*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVTRANS:
890*61046927SAndroid Build Coastguard Worker return _NEW_TRACK_MATRIX;
891*61046927SAndroid Build Coastguard Worker
892*61046927SAndroid Build Coastguard Worker case STATE_NUM_SAMPLES:
893*61046927SAndroid Build Coastguard Worker case STATE_FB_SIZE:
894*61046927SAndroid Build Coastguard Worker case STATE_FB_WPOS_Y_TRANSFORM:
895*61046927SAndroid Build Coastguard Worker return _NEW_BUFFERS;
896*61046927SAndroid Build Coastguard Worker
897*61046927SAndroid Build Coastguard Worker case STATE_FB_PNTC_Y_TRANSFORM:
898*61046927SAndroid Build Coastguard Worker return _NEW_BUFFERS | _NEW_POINT;
899*61046927SAndroid Build Coastguard Worker
900*61046927SAndroid Build Coastguard Worker case STATE_DEPTH_RANGE:
901*61046927SAndroid Build Coastguard Worker return _NEW_VIEWPORT;
902*61046927SAndroid Build Coastguard Worker
903*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV:
904*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV_ARRAY:
905*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL:
906*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY:
907*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV:
908*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV_ARRAY:
909*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL:
910*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL_ARRAY:
911*61046927SAndroid Build Coastguard Worker return _NEW_PROGRAM;
912*61046927SAndroid Build Coastguard Worker
913*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB:
914*61046927SAndroid Build Coastguard Worker return _NEW_CURRENT_ATTRIB;
915*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
916*61046927SAndroid Build Coastguard Worker return _NEW_CURRENT_ATTRIB | _NEW_LIGHT_STATE | _NEW_BUFFERS;
917*61046927SAndroid Build Coastguard Worker
918*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE_CLAMPED:
919*61046927SAndroid Build Coastguard Worker return _NEW_POINT | _NEW_MULTISAMPLE;
920*61046927SAndroid Build Coastguard Worker
921*61046927SAndroid Build Coastguard Worker case STATE_PT_SCALE:
922*61046927SAndroid Build Coastguard Worker case STATE_PT_BIAS:
923*61046927SAndroid Build Coastguard Worker return _NEW_PIXEL;
924*61046927SAndroid Build Coastguard Worker
925*61046927SAndroid Build Coastguard Worker case STATE_ADVANCED_BLENDING_MODE:
926*61046927SAndroid Build Coastguard Worker case STATE_ALPHA_REF:
927*61046927SAndroid Build Coastguard Worker return _NEW_COLOR;
928*61046927SAndroid Build Coastguard Worker
929*61046927SAndroid Build Coastguard Worker case STATE_CLIP_INTERNAL:
930*61046927SAndroid Build Coastguard Worker return _NEW_TRANSFORM | _NEW_PROJECTION;
931*61046927SAndroid Build Coastguard Worker
932*61046927SAndroid Build Coastguard Worker /* Needs to return any nonzero value to trigger constant updating */
933*61046927SAndroid Build Coastguard Worker case STATE_ATOMIC_COUNTER_OFFSET:
934*61046927SAndroid Build Coastguard Worker return _NEW_PROGRAM_CONSTANTS;
935*61046927SAndroid Build Coastguard Worker
936*61046927SAndroid Build Coastguard Worker case STATE_TCS_PATCH_VERTICES_IN:
937*61046927SAndroid Build Coastguard Worker case STATE_TES_PATCH_VERTICES_IN:
938*61046927SAndroid Build Coastguard Worker case STATE_INTERNAL_DRIVER:
939*61046927SAndroid Build Coastguard Worker return 0; /* internal driver state */
940*61046927SAndroid Build Coastguard Worker
941*61046927SAndroid Build Coastguard Worker case STATE_NOT_STATE_VAR:
942*61046927SAndroid Build Coastguard Worker return 0;
943*61046927SAndroid Build Coastguard Worker
944*61046927SAndroid Build Coastguard Worker default:
945*61046927SAndroid Build Coastguard Worker _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
946*61046927SAndroid Build Coastguard Worker return 0;
947*61046927SAndroid Build Coastguard Worker }
948*61046927SAndroid Build Coastguard Worker }
949*61046927SAndroid Build Coastguard Worker
950*61046927SAndroid Build Coastguard Worker
951*61046927SAndroid Build Coastguard Worker static void
append(char * dst,const char * src)952*61046927SAndroid Build Coastguard Worker append(char *dst, const char *src)
953*61046927SAndroid Build Coastguard Worker {
954*61046927SAndroid Build Coastguard Worker while (*dst)
955*61046927SAndroid Build Coastguard Worker dst++;
956*61046927SAndroid Build Coastguard Worker while (*src)
957*61046927SAndroid Build Coastguard Worker *dst++ = *src++;
958*61046927SAndroid Build Coastguard Worker *dst = 0;
959*61046927SAndroid Build Coastguard Worker }
960*61046927SAndroid Build Coastguard Worker
961*61046927SAndroid Build Coastguard Worker
962*61046927SAndroid Build Coastguard Worker /**
963*61046927SAndroid Build Coastguard Worker * Convert token 'k' to a string, append it onto 'dst' string.
964*61046927SAndroid Build Coastguard Worker */
965*61046927SAndroid Build Coastguard Worker static void
append_token(char * dst,gl_state_index k)966*61046927SAndroid Build Coastguard Worker append_token(char *dst, gl_state_index k)
967*61046927SAndroid Build Coastguard Worker {
968*61046927SAndroid Build Coastguard Worker switch (k) {
969*61046927SAndroid Build Coastguard Worker case STATE_MATERIAL:
970*61046927SAndroid Build Coastguard Worker append(dst, "material");
971*61046927SAndroid Build Coastguard Worker break;
972*61046927SAndroid Build Coastguard Worker case STATE_LIGHT:
973*61046927SAndroid Build Coastguard Worker append(dst, "light");
974*61046927SAndroid Build Coastguard Worker break;
975*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ARRAY:
976*61046927SAndroid Build Coastguard Worker append(dst, "light.array");
977*61046927SAndroid Build Coastguard Worker break;
978*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ATTENUATION_ARRAY:
979*61046927SAndroid Build Coastguard Worker append(dst, "light.attenuation");
980*61046927SAndroid Build Coastguard Worker break;
981*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_AMBIENT:
982*61046927SAndroid Build Coastguard Worker append(dst, "lightmodel.ambient");
983*61046927SAndroid Build Coastguard Worker break;
984*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_SCENECOLOR:
985*61046927SAndroid Build Coastguard Worker break;
986*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD:
987*61046927SAndroid Build Coastguard Worker append(dst, "lightprod");
988*61046927SAndroid Build Coastguard Worker break;
989*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_FRONT:
990*61046927SAndroid Build Coastguard Worker append(dst, "lightprod.array.front");
991*61046927SAndroid Build Coastguard Worker break;
992*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_BACK:
993*61046927SAndroid Build Coastguard Worker append(dst, "lightprod.array.back");
994*61046927SAndroid Build Coastguard Worker break;
995*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_TWOSIDE:
996*61046927SAndroid Build Coastguard Worker append(dst, "lightprod.array.twoside");
997*61046927SAndroid Build Coastguard Worker break;
998*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN:
999*61046927SAndroid Build Coastguard Worker append(dst, "texgen");
1000*61046927SAndroid Build Coastguard Worker break;
1001*61046927SAndroid Build Coastguard Worker case STATE_FOG_COLOR:
1002*61046927SAndroid Build Coastguard Worker append(dst, "fog.color");
1003*61046927SAndroid Build Coastguard Worker break;
1004*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS:
1005*61046927SAndroid Build Coastguard Worker append(dst, "fog.params");
1006*61046927SAndroid Build Coastguard Worker break;
1007*61046927SAndroid Build Coastguard Worker case STATE_CLIPPLANE:
1008*61046927SAndroid Build Coastguard Worker append(dst, "clip");
1009*61046927SAndroid Build Coastguard Worker break;
1010*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE:
1011*61046927SAndroid Build Coastguard Worker append(dst, "point.size");
1012*61046927SAndroid Build Coastguard Worker break;
1013*61046927SAndroid Build Coastguard Worker case STATE_POINT_ATTENUATION:
1014*61046927SAndroid Build Coastguard Worker append(dst, "point.attenuation");
1015*61046927SAndroid Build Coastguard Worker break;
1016*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX:
1017*61046927SAndroid Build Coastguard Worker append(dst, "matrix.modelview.");
1018*61046927SAndroid Build Coastguard Worker break;
1019*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVERSE:
1020*61046927SAndroid Build Coastguard Worker append(dst, "matrix.modelview.inverse.");
1021*61046927SAndroid Build Coastguard Worker break;
1022*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_TRANSPOSE:
1023*61046927SAndroid Build Coastguard Worker append(dst, "matrix.modelview.transpose.");
1024*61046927SAndroid Build Coastguard Worker break;
1025*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVTRANS:
1026*61046927SAndroid Build Coastguard Worker append(dst, "matrix.modelview.invtrans.");
1027*61046927SAndroid Build Coastguard Worker break;
1028*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX:
1029*61046927SAndroid Build Coastguard Worker append(dst, "matrix.projection.");
1030*61046927SAndroid Build Coastguard Worker break;
1031*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVERSE:
1032*61046927SAndroid Build Coastguard Worker append(dst, "matrix.projection.inverse.");
1033*61046927SAndroid Build Coastguard Worker break;
1034*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_TRANSPOSE:
1035*61046927SAndroid Build Coastguard Worker append(dst, "matrix.projection.transpose.");
1036*61046927SAndroid Build Coastguard Worker break;
1037*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVTRANS:
1038*61046927SAndroid Build Coastguard Worker append(dst, "matrix.projection.invtrans.");
1039*61046927SAndroid Build Coastguard Worker break;
1040*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX:
1041*61046927SAndroid Build Coastguard Worker append(dst, "matrix.mvp.");
1042*61046927SAndroid Build Coastguard Worker break;
1043*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVERSE:
1044*61046927SAndroid Build Coastguard Worker append(dst, "matrix.mvp.inverse.");
1045*61046927SAndroid Build Coastguard Worker break;
1046*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_TRANSPOSE:
1047*61046927SAndroid Build Coastguard Worker append(dst, "matrix.mvp.transpose.");
1048*61046927SAndroid Build Coastguard Worker break;
1049*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVTRANS:
1050*61046927SAndroid Build Coastguard Worker append(dst, "matrix.mvp.invtrans.");
1051*61046927SAndroid Build Coastguard Worker break;
1052*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX:
1053*61046927SAndroid Build Coastguard Worker append(dst, "matrix.texture");
1054*61046927SAndroid Build Coastguard Worker break;
1055*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVERSE:
1056*61046927SAndroid Build Coastguard Worker append(dst, "matrix.texture.inverse");
1057*61046927SAndroid Build Coastguard Worker break;
1058*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_TRANSPOSE:
1059*61046927SAndroid Build Coastguard Worker append(dst, "matrix.texture.transpose");
1060*61046927SAndroid Build Coastguard Worker break;
1061*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVTRANS:
1062*61046927SAndroid Build Coastguard Worker append(dst, "matrix.texture.invtrans");
1063*61046927SAndroid Build Coastguard Worker break;
1064*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX:
1065*61046927SAndroid Build Coastguard Worker append(dst, "matrix.program");
1066*61046927SAndroid Build Coastguard Worker break;
1067*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVERSE:
1068*61046927SAndroid Build Coastguard Worker append(dst, "matrix.program.inverse");
1069*61046927SAndroid Build Coastguard Worker break;
1070*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_TRANSPOSE:
1071*61046927SAndroid Build Coastguard Worker append(dst, "matrix.program.transpose");
1072*61046927SAndroid Build Coastguard Worker break;
1073*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVTRANS:
1074*61046927SAndroid Build Coastguard Worker append(dst, "matrix.program.invtrans");
1075*61046927SAndroid Build Coastguard Worker break;
1076*61046927SAndroid Build Coastguard Worker break;
1077*61046927SAndroid Build Coastguard Worker case STATE_AMBIENT:
1078*61046927SAndroid Build Coastguard Worker append(dst, "ambient");
1079*61046927SAndroid Build Coastguard Worker break;
1080*61046927SAndroid Build Coastguard Worker case STATE_DIFFUSE:
1081*61046927SAndroid Build Coastguard Worker append(dst, "diffuse");
1082*61046927SAndroid Build Coastguard Worker break;
1083*61046927SAndroid Build Coastguard Worker case STATE_SPECULAR:
1084*61046927SAndroid Build Coastguard Worker append(dst, "specular");
1085*61046927SAndroid Build Coastguard Worker break;
1086*61046927SAndroid Build Coastguard Worker case STATE_EMISSION:
1087*61046927SAndroid Build Coastguard Worker append(dst, "emission");
1088*61046927SAndroid Build Coastguard Worker break;
1089*61046927SAndroid Build Coastguard Worker case STATE_SHININESS:
1090*61046927SAndroid Build Coastguard Worker append(dst, "shininess");
1091*61046927SAndroid Build Coastguard Worker break;
1092*61046927SAndroid Build Coastguard Worker case STATE_HALF_VECTOR:
1093*61046927SAndroid Build Coastguard Worker append(dst, "half");
1094*61046927SAndroid Build Coastguard Worker break;
1095*61046927SAndroid Build Coastguard Worker case STATE_POSITION:
1096*61046927SAndroid Build Coastguard Worker append(dst, "position");
1097*61046927SAndroid Build Coastguard Worker break;
1098*61046927SAndroid Build Coastguard Worker case STATE_ATTENUATION:
1099*61046927SAndroid Build Coastguard Worker append(dst, "attenuation");
1100*61046927SAndroid Build Coastguard Worker break;
1101*61046927SAndroid Build Coastguard Worker case STATE_SPOT_DIRECTION:
1102*61046927SAndroid Build Coastguard Worker append(dst, "spot.direction");
1103*61046927SAndroid Build Coastguard Worker break;
1104*61046927SAndroid Build Coastguard Worker case STATE_SPOT_CUTOFF:
1105*61046927SAndroid Build Coastguard Worker append(dst, "spot.cutoff");
1106*61046927SAndroid Build Coastguard Worker break;
1107*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_EYE_S:
1108*61046927SAndroid Build Coastguard Worker append(dst, "eye.s");
1109*61046927SAndroid Build Coastguard Worker break;
1110*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_EYE_T:
1111*61046927SAndroid Build Coastguard Worker append(dst, "eye.t");
1112*61046927SAndroid Build Coastguard Worker break;
1113*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_EYE_R:
1114*61046927SAndroid Build Coastguard Worker append(dst, "eye.r");
1115*61046927SAndroid Build Coastguard Worker break;
1116*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_EYE_Q:
1117*61046927SAndroid Build Coastguard Worker append(dst, "eye.q");
1118*61046927SAndroid Build Coastguard Worker break;
1119*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_OBJECT_S:
1120*61046927SAndroid Build Coastguard Worker append(dst, "object.s");
1121*61046927SAndroid Build Coastguard Worker break;
1122*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_OBJECT_T:
1123*61046927SAndroid Build Coastguard Worker append(dst, "object.t");
1124*61046927SAndroid Build Coastguard Worker break;
1125*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_OBJECT_R:
1126*61046927SAndroid Build Coastguard Worker append(dst, "object.r");
1127*61046927SAndroid Build Coastguard Worker break;
1128*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN_OBJECT_Q:
1129*61046927SAndroid Build Coastguard Worker append(dst, "object.q");
1130*61046927SAndroid Build Coastguard Worker break;
1131*61046927SAndroid Build Coastguard Worker case STATE_TEXENV_COLOR:
1132*61046927SAndroid Build Coastguard Worker append(dst, "texenv");
1133*61046927SAndroid Build Coastguard Worker break;
1134*61046927SAndroid Build Coastguard Worker case STATE_NUM_SAMPLES:
1135*61046927SAndroid Build Coastguard Worker append(dst, "numsamples");
1136*61046927SAndroid Build Coastguard Worker break;
1137*61046927SAndroid Build Coastguard Worker case STATE_DEPTH_RANGE:
1138*61046927SAndroid Build Coastguard Worker append(dst, "depth.range");
1139*61046927SAndroid Build Coastguard Worker break;
1140*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV:
1141*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV:
1142*61046927SAndroid Build Coastguard Worker append(dst, "env");
1143*61046927SAndroid Build Coastguard Worker break;
1144*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV_ARRAY:
1145*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV_ARRAY:
1146*61046927SAndroid Build Coastguard Worker append(dst, "env.range");
1147*61046927SAndroid Build Coastguard Worker break;
1148*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL:
1149*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL:
1150*61046927SAndroid Build Coastguard Worker append(dst, "local");
1151*61046927SAndroid Build Coastguard Worker break;
1152*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL_ARRAY:
1153*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY:
1154*61046927SAndroid Build Coastguard Worker append(dst, "local.range");
1155*61046927SAndroid Build Coastguard Worker break;
1156*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB:
1157*61046927SAndroid Build Coastguard Worker append(dst, "current");
1158*61046927SAndroid Build Coastguard Worker break;
1159*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
1160*61046927SAndroid Build Coastguard Worker append(dst, "currentAttribMaybeVPClamped");
1161*61046927SAndroid Build Coastguard Worker break;
1162*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE_EYESPACE:
1163*61046927SAndroid Build Coastguard Worker append(dst, "normalScaleEyeSpace");
1164*61046927SAndroid Build Coastguard Worker break;
1165*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE:
1166*61046927SAndroid Build Coastguard Worker append(dst, "normalScale");
1167*61046927SAndroid Build Coastguard Worker break;
1168*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS_OPTIMIZED:
1169*61046927SAndroid Build Coastguard Worker append(dst, "fogParamsOptimized");
1170*61046927SAndroid Build Coastguard Worker break;
1171*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE_CLAMPED:
1172*61046927SAndroid Build Coastguard Worker append(dst, "pointSizeClamped");
1173*61046927SAndroid Build Coastguard Worker break;
1174*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_SPOT_DIR_NORMALIZED:
1175*61046927SAndroid Build Coastguard Worker append(dst, "lightSpotDirNormalized");
1176*61046927SAndroid Build Coastguard Worker break;
1177*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION:
1178*61046927SAndroid Build Coastguard Worker append(dst, "light.position");
1179*61046927SAndroid Build Coastguard Worker break;
1180*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_ARRAY:
1181*61046927SAndroid Build Coastguard Worker append(dst, "light.position.array");
1182*61046927SAndroid Build Coastguard Worker break;
1183*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED:
1184*61046927SAndroid Build Coastguard Worker append(dst, "light.position.normalized");
1185*61046927SAndroid Build Coastguard Worker break;
1186*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED_ARRAY:
1187*61046927SAndroid Build Coastguard Worker append(dst, "light.position.normalized.array");
1188*61046927SAndroid Build Coastguard Worker break;
1189*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_HALF_VECTOR:
1190*61046927SAndroid Build Coastguard Worker append(dst, "lightHalfVector");
1191*61046927SAndroid Build Coastguard Worker break;
1192*61046927SAndroid Build Coastguard Worker case STATE_PT_SCALE:
1193*61046927SAndroid Build Coastguard Worker append(dst, "PTscale");
1194*61046927SAndroid Build Coastguard Worker break;
1195*61046927SAndroid Build Coastguard Worker case STATE_PT_BIAS:
1196*61046927SAndroid Build Coastguard Worker append(dst, "PTbias");
1197*61046927SAndroid Build Coastguard Worker break;
1198*61046927SAndroid Build Coastguard Worker case STATE_FB_SIZE:
1199*61046927SAndroid Build Coastguard Worker append(dst, "FbSize");
1200*61046927SAndroid Build Coastguard Worker break;
1201*61046927SAndroid Build Coastguard Worker case STATE_FB_WPOS_Y_TRANSFORM:
1202*61046927SAndroid Build Coastguard Worker append(dst, "FbWposYTransform");
1203*61046927SAndroid Build Coastguard Worker break;
1204*61046927SAndroid Build Coastguard Worker case STATE_FB_PNTC_Y_TRANSFORM:
1205*61046927SAndroid Build Coastguard Worker append(dst, "PntcYTransform");
1206*61046927SAndroid Build Coastguard Worker break;
1207*61046927SAndroid Build Coastguard Worker case STATE_ADVANCED_BLENDING_MODE:
1208*61046927SAndroid Build Coastguard Worker append(dst, "AdvancedBlendingMode");
1209*61046927SAndroid Build Coastguard Worker break;
1210*61046927SAndroid Build Coastguard Worker case STATE_ALPHA_REF:
1211*61046927SAndroid Build Coastguard Worker append(dst, "alphaRef");
1212*61046927SAndroid Build Coastguard Worker break;
1213*61046927SAndroid Build Coastguard Worker case STATE_CLIP_INTERNAL:
1214*61046927SAndroid Build Coastguard Worker append(dst, "clipInternal");
1215*61046927SAndroid Build Coastguard Worker break;
1216*61046927SAndroid Build Coastguard Worker case STATE_ATOMIC_COUNTER_OFFSET:
1217*61046927SAndroid Build Coastguard Worker append(dst, "counterOffset");
1218*61046927SAndroid Build Coastguard Worker break;
1219*61046927SAndroid Build Coastguard Worker default:
1220*61046927SAndroid Build Coastguard Worker /* probably STATE_INTERNAL_DRIVER+i (driver private state) */
1221*61046927SAndroid Build Coastguard Worker append(dst, "driverState");
1222*61046927SAndroid Build Coastguard Worker }
1223*61046927SAndroid Build Coastguard Worker }
1224*61046927SAndroid Build Coastguard Worker
1225*61046927SAndroid Build Coastguard Worker static void
append_index(char * dst,GLint index,bool structure)1226*61046927SAndroid Build Coastguard Worker append_index(char *dst, GLint index, bool structure)
1227*61046927SAndroid Build Coastguard Worker {
1228*61046927SAndroid Build Coastguard Worker char s[20];
1229*61046927SAndroid Build Coastguard Worker sprintf(s, "[%d]%s", index, structure ? "." : "");
1230*61046927SAndroid Build Coastguard Worker append(dst, s);
1231*61046927SAndroid Build Coastguard Worker }
1232*61046927SAndroid Build Coastguard Worker
1233*61046927SAndroid Build Coastguard Worker /**
1234*61046927SAndroid Build Coastguard Worker * Make a string from the given state vector.
1235*61046927SAndroid Build Coastguard Worker * For example, return "state.matrix.texture[2].inverse".
1236*61046927SAndroid Build Coastguard Worker * Use free() to deallocate the string.
1237*61046927SAndroid Build Coastguard Worker */
1238*61046927SAndroid Build Coastguard Worker char *
_mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH])1239*61046927SAndroid Build Coastguard Worker _mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH])
1240*61046927SAndroid Build Coastguard Worker {
1241*61046927SAndroid Build Coastguard Worker char str[1000] = "";
1242*61046927SAndroid Build Coastguard Worker char tmp[30];
1243*61046927SAndroid Build Coastguard Worker
1244*61046927SAndroid Build Coastguard Worker append(str, "state.");
1245*61046927SAndroid Build Coastguard Worker append_token(str, state[0]);
1246*61046927SAndroid Build Coastguard Worker
1247*61046927SAndroid Build Coastguard Worker switch (state[0]) {
1248*61046927SAndroid Build Coastguard Worker case STATE_LIGHT:
1249*61046927SAndroid Build Coastguard Worker append_index(str, state[1], true); /* light number [i]. */
1250*61046927SAndroid Build Coastguard Worker append_token(str, state[2]); /* coefficients */
1251*61046927SAndroid Build Coastguard Worker break;
1252*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_AMBIENT:
1253*61046927SAndroid Build Coastguard Worker break;
1254*61046927SAndroid Build Coastguard Worker case STATE_LIGHTMODEL_SCENECOLOR:
1255*61046927SAndroid Build Coastguard Worker if (state[1] == 0) {
1256*61046927SAndroid Build Coastguard Worker append(str, "lightmodel.front.scenecolor");
1257*61046927SAndroid Build Coastguard Worker }
1258*61046927SAndroid Build Coastguard Worker else {
1259*61046927SAndroid Build Coastguard Worker append(str, "lightmodel.back.scenecolor");
1260*61046927SAndroid Build Coastguard Worker }
1261*61046927SAndroid Build Coastguard Worker break;
1262*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD:
1263*61046927SAndroid Build Coastguard Worker append_index(str, state[1], false); /* light number [i] */
1264*61046927SAndroid Build Coastguard Worker append_index(str, state[2], false);
1265*61046927SAndroid Build Coastguard Worker break;
1266*61046927SAndroid Build Coastguard Worker case STATE_TEXGEN:
1267*61046927SAndroid Build Coastguard Worker append_index(str, state[1], true); /* tex unit [i] */
1268*61046927SAndroid Build Coastguard Worker append_token(str, state[2]); /* plane coef */
1269*61046927SAndroid Build Coastguard Worker break;
1270*61046927SAndroid Build Coastguard Worker case STATE_TEXENV_COLOR:
1271*61046927SAndroid Build Coastguard Worker append_index(str, state[1], true); /* tex unit [i] */
1272*61046927SAndroid Build Coastguard Worker append(str, "color");
1273*61046927SAndroid Build Coastguard Worker break;
1274*61046927SAndroid Build Coastguard Worker case STATE_CLIPPLANE:
1275*61046927SAndroid Build Coastguard Worker append_index(str, state[1], true); /* plane [i] */
1276*61046927SAndroid Build Coastguard Worker append(str, "plane");
1277*61046927SAndroid Build Coastguard Worker break;
1278*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX:
1279*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVERSE:
1280*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_TRANSPOSE:
1281*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVTRANS:
1282*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX:
1283*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVERSE:
1284*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_TRANSPOSE:
1285*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVTRANS:
1286*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX:
1287*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVERSE:
1288*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_TRANSPOSE:
1289*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVTRANS:
1290*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX:
1291*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVERSE:
1292*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_TRANSPOSE:
1293*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVTRANS:
1294*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX:
1295*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVERSE:
1296*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_TRANSPOSE:
1297*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVTRANS:
1298*61046927SAndroid Build Coastguard Worker {
1299*61046927SAndroid Build Coastguard Worker /* state[0] = modelview, projection, texture, etc. */
1300*61046927SAndroid Build Coastguard Worker /* state[1] = which texture matrix or program matrix */
1301*61046927SAndroid Build Coastguard Worker /* state[2] = first row to fetch */
1302*61046927SAndroid Build Coastguard Worker /* state[3] = last row to fetch */
1303*61046927SAndroid Build Coastguard Worker const gl_state_index mat = state[0];
1304*61046927SAndroid Build Coastguard Worker const GLuint index = (GLuint) state[1];
1305*61046927SAndroid Build Coastguard Worker const GLuint firstRow = (GLuint) state[2];
1306*61046927SAndroid Build Coastguard Worker const GLuint lastRow = (GLuint) state[3];
1307*61046927SAndroid Build Coastguard Worker if (index ||
1308*61046927SAndroid Build Coastguard Worker (mat >= STATE_TEXTURE_MATRIX &&
1309*61046927SAndroid Build Coastguard Worker mat <= STATE_PROGRAM_MATRIX_INVTRANS))
1310*61046927SAndroid Build Coastguard Worker append_index(str, index, true);
1311*61046927SAndroid Build Coastguard Worker if (firstRow == lastRow)
1312*61046927SAndroid Build Coastguard Worker sprintf(tmp, "row[%d]", firstRow);
1313*61046927SAndroid Build Coastguard Worker else
1314*61046927SAndroid Build Coastguard Worker sprintf(tmp, "row[%d..%d]", firstRow, lastRow);
1315*61046927SAndroid Build Coastguard Worker append(str, tmp);
1316*61046927SAndroid Build Coastguard Worker }
1317*61046927SAndroid Build Coastguard Worker break;
1318*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ARRAY:
1319*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_ATTENUATION_ARRAY:
1320*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV_ARRAY:
1321*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY:
1322*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV_ARRAY:
1323*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL_ARRAY:
1324*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_FRONT:
1325*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_BACK:
1326*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_TWOSIDE:
1327*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_ARRAY:
1328*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED_ARRAY:
1329*61046927SAndroid Build Coastguard Worker sprintf(tmp, "[%d..%d]", state[1], state[1] + state[2] - 1);
1330*61046927SAndroid Build Coastguard Worker append(str, tmp);
1331*61046927SAndroid Build Coastguard Worker break;
1332*61046927SAndroid Build Coastguard Worker case STATE_MATERIAL:
1333*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV:
1334*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL:
1335*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV:
1336*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL:
1337*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB:
1338*61046927SAndroid Build Coastguard Worker case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
1339*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_SPOT_DIR_NORMALIZED:
1340*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION:
1341*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED:
1342*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_HALF_VECTOR:
1343*61046927SAndroid Build Coastguard Worker case STATE_CLIP_INTERNAL:
1344*61046927SAndroid Build Coastguard Worker case STATE_ATOMIC_COUNTER_OFFSET:
1345*61046927SAndroid Build Coastguard Worker append_index(str, state[1], false);
1346*61046927SAndroid Build Coastguard Worker break;
1347*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE:
1348*61046927SAndroid Build Coastguard Worker case STATE_POINT_ATTENUATION:
1349*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS:
1350*61046927SAndroid Build Coastguard Worker case STATE_FOG_COLOR:
1351*61046927SAndroid Build Coastguard Worker case STATE_NUM_SAMPLES:
1352*61046927SAndroid Build Coastguard Worker case STATE_DEPTH_RANGE:
1353*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE_EYESPACE:
1354*61046927SAndroid Build Coastguard Worker case STATE_NORMAL_SCALE:
1355*61046927SAndroid Build Coastguard Worker case STATE_FOG_PARAMS_OPTIMIZED:
1356*61046927SAndroid Build Coastguard Worker case STATE_POINT_SIZE_CLAMPED:
1357*61046927SAndroid Build Coastguard Worker case STATE_PT_SCALE:
1358*61046927SAndroid Build Coastguard Worker case STATE_PT_BIAS:
1359*61046927SAndroid Build Coastguard Worker case STATE_FB_SIZE:
1360*61046927SAndroid Build Coastguard Worker case STATE_FB_WPOS_Y_TRANSFORM:
1361*61046927SAndroid Build Coastguard Worker case STATE_FB_PNTC_Y_TRANSFORM:
1362*61046927SAndroid Build Coastguard Worker case STATE_TCS_PATCH_VERTICES_IN:
1363*61046927SAndroid Build Coastguard Worker case STATE_TES_PATCH_VERTICES_IN:
1364*61046927SAndroid Build Coastguard Worker case STATE_ADVANCED_BLENDING_MODE:
1365*61046927SAndroid Build Coastguard Worker case STATE_ALPHA_REF:
1366*61046927SAndroid Build Coastguard Worker break;
1367*61046927SAndroid Build Coastguard Worker case STATE_NOT_STATE_VAR:
1368*61046927SAndroid Build Coastguard Worker append(str, "not_state");
1369*61046927SAndroid Build Coastguard Worker break;
1370*61046927SAndroid Build Coastguard Worker default:
1371*61046927SAndroid Build Coastguard Worker _mesa_problem(NULL, "Invalid state in _mesa_program_state_string: %d", state[0]);
1372*61046927SAndroid Build Coastguard Worker break;
1373*61046927SAndroid Build Coastguard Worker }
1374*61046927SAndroid Build Coastguard Worker
1375*61046927SAndroid Build Coastguard Worker return strdup(str);
1376*61046927SAndroid Build Coastguard Worker }
1377*61046927SAndroid Build Coastguard Worker
1378*61046927SAndroid Build Coastguard Worker
1379*61046927SAndroid Build Coastguard Worker /**
1380*61046927SAndroid Build Coastguard Worker * Loop over all the parameters in a parameter list. If the parameter
1381*61046927SAndroid Build Coastguard Worker * is a GL state reference, look up the current value of that state
1382*61046927SAndroid Build Coastguard Worker * variable and put it into the parameter's Value[4] array.
1383*61046927SAndroid Build Coastguard Worker * Other parameter types never change or are explicitly set by the user
1384*61046927SAndroid Build Coastguard Worker * with glUniform() or glProgramParameter(), etc.
1385*61046927SAndroid Build Coastguard Worker * This would be called at glBegin time.
1386*61046927SAndroid Build Coastguard Worker */
1387*61046927SAndroid Build Coastguard Worker void
_mesa_load_state_parameters(struct gl_context * ctx,struct gl_program_parameter_list * paramList)1388*61046927SAndroid Build Coastguard Worker _mesa_load_state_parameters(struct gl_context *ctx,
1389*61046927SAndroid Build Coastguard Worker struct gl_program_parameter_list *paramList)
1390*61046927SAndroid Build Coastguard Worker {
1391*61046927SAndroid Build Coastguard Worker if (!paramList)
1392*61046927SAndroid Build Coastguard Worker return;
1393*61046927SAndroid Build Coastguard Worker
1394*61046927SAndroid Build Coastguard Worker int last = paramList->LastStateVarIndex;
1395*61046927SAndroid Build Coastguard Worker
1396*61046927SAndroid Build Coastguard Worker for (int i = paramList->FirstStateVarIndex; i <= last; i++) {
1397*61046927SAndroid Build Coastguard Worker unsigned pvo = paramList->Parameters[i].ValueOffset;
1398*61046927SAndroid Build Coastguard Worker fetch_state(ctx, paramList->Parameters[i].StateIndexes,
1399*61046927SAndroid Build Coastguard Worker paramList->ParameterValues + pvo);
1400*61046927SAndroid Build Coastguard Worker }
1401*61046927SAndroid Build Coastguard Worker }
1402*61046927SAndroid Build Coastguard Worker
1403*61046927SAndroid Build Coastguard Worker void
_mesa_upload_state_parameters(struct gl_context * ctx,struct gl_program_parameter_list * paramList,uint32_t * dst)1404*61046927SAndroid Build Coastguard Worker _mesa_upload_state_parameters(struct gl_context *ctx,
1405*61046927SAndroid Build Coastguard Worker struct gl_program_parameter_list *paramList,
1406*61046927SAndroid Build Coastguard Worker uint32_t *dst)
1407*61046927SAndroid Build Coastguard Worker {
1408*61046927SAndroid Build Coastguard Worker int last = paramList->LastStateVarIndex;
1409*61046927SAndroid Build Coastguard Worker
1410*61046927SAndroid Build Coastguard Worker for (int i = paramList->FirstStateVarIndex; i <= last; i++) {
1411*61046927SAndroid Build Coastguard Worker unsigned pvo = paramList->Parameters[i].ValueOffset;
1412*61046927SAndroid Build Coastguard Worker fetch_state(ctx, paramList->Parameters[i].StateIndexes,
1413*61046927SAndroid Build Coastguard Worker (gl_constant_value*)(dst + pvo));
1414*61046927SAndroid Build Coastguard Worker }
1415*61046927SAndroid Build Coastguard Worker }
1416*61046927SAndroid Build Coastguard Worker
1417*61046927SAndroid Build Coastguard Worker /* Merge consecutive state vars into one for the state vars that allow
1418*61046927SAndroid Build Coastguard Worker * multiple vec4s.
1419*61046927SAndroid Build Coastguard Worker *
1420*61046927SAndroid Build Coastguard Worker * This should be done after shader compilation, so that drivers don't
1421*61046927SAndroid Build Coastguard Worker * have to deal with multi-slot state parameters in their backends.
1422*61046927SAndroid Build Coastguard Worker * It's only meant to optimize _mesa_load/upload_state_parameters.
1423*61046927SAndroid Build Coastguard Worker */
1424*61046927SAndroid Build Coastguard Worker void
_mesa_optimize_state_parameters(struct gl_constants * consts,struct gl_program_parameter_list * list)1425*61046927SAndroid Build Coastguard Worker _mesa_optimize_state_parameters(struct gl_constants *consts,
1426*61046927SAndroid Build Coastguard Worker struct gl_program_parameter_list *list)
1427*61046927SAndroid Build Coastguard Worker {
1428*61046927SAndroid Build Coastguard Worker for (int first_param = list->FirstStateVarIndex;
1429*61046927SAndroid Build Coastguard Worker first_param < (int)list->NumParameters; first_param++) {
1430*61046927SAndroid Build Coastguard Worker int last_param = first_param;
1431*61046927SAndroid Build Coastguard Worker int param_diff = 0;
1432*61046927SAndroid Build Coastguard Worker
1433*61046927SAndroid Build Coastguard Worker switch (list->Parameters[first_param].StateIndexes[0]) {
1434*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX:
1435*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVERSE:
1436*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_TRANSPOSE:
1437*61046927SAndroid Build Coastguard Worker case STATE_MODELVIEW_MATRIX_INVTRANS:
1438*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX:
1439*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVERSE:
1440*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_TRANSPOSE:
1441*61046927SAndroid Build Coastguard Worker case STATE_PROJECTION_MATRIX_INVTRANS:
1442*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX:
1443*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVERSE:
1444*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_TRANSPOSE:
1445*61046927SAndroid Build Coastguard Worker case STATE_MVP_MATRIX_INVTRANS:
1446*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX:
1447*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVERSE:
1448*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_TRANSPOSE:
1449*61046927SAndroid Build Coastguard Worker case STATE_TEXTURE_MATRIX_INVTRANS:
1450*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX:
1451*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVERSE:
1452*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_TRANSPOSE:
1453*61046927SAndroid Build Coastguard Worker case STATE_PROGRAM_MATRIX_INVTRANS:
1454*61046927SAndroid Build Coastguard Worker /* Skip unaligned state vars. */
1455*61046927SAndroid Build Coastguard Worker if (list->Parameters[first_param].Size % 4)
1456*61046927SAndroid Build Coastguard Worker break;
1457*61046927SAndroid Build Coastguard Worker
1458*61046927SAndroid Build Coastguard Worker /* Search for adjacent state vars that refer to adjacent rows. */
1459*61046927SAndroid Build Coastguard Worker for (int i = first_param + 1; i < (int)list->NumParameters; i++) {
1460*61046927SAndroid Build Coastguard Worker if (list->Parameters[i].StateIndexes[0] ==
1461*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[0] &&
1462*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[1] ==
1463*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[1] &&
1464*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[2] == /* FirstRow */
1465*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[3] + 1 && /* LastRow + 1 */
1466*61046927SAndroid Build Coastguard Worker list->Parameters[i].Size == 4) {
1467*61046927SAndroid Build Coastguard Worker last_param = i;
1468*61046927SAndroid Build Coastguard Worker continue;
1469*61046927SAndroid Build Coastguard Worker }
1470*61046927SAndroid Build Coastguard Worker break; /* The adjacent state var is incompatible. */
1471*61046927SAndroid Build Coastguard Worker }
1472*61046927SAndroid Build Coastguard Worker if (last_param > first_param) {
1473*61046927SAndroid Build Coastguard Worker int first_vec = list->Parameters[first_param].StateIndexes[2];
1474*61046927SAndroid Build Coastguard Worker int last_vec = list->Parameters[last_param].StateIndexes[3];
1475*61046927SAndroid Build Coastguard Worker
1476*61046927SAndroid Build Coastguard Worker assert(first_vec < last_vec);
1477*61046927SAndroid Build Coastguard Worker assert(last_vec - first_vec == last_param - first_param);
1478*61046927SAndroid Build Coastguard Worker
1479*61046927SAndroid Build Coastguard Worker /* Update LastRow. */
1480*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[3] = last_vec;
1481*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].Size = (last_vec - first_vec + 1) * 4;
1482*61046927SAndroid Build Coastguard Worker
1483*61046927SAndroid Build Coastguard Worker param_diff = last_param - first_param;
1484*61046927SAndroid Build Coastguard Worker }
1485*61046927SAndroid Build Coastguard Worker break;
1486*61046927SAndroid Build Coastguard Worker
1487*61046927SAndroid Build Coastguard Worker case STATE_LIGHT:
1488*61046927SAndroid Build Coastguard Worker /* Skip trimmed state vars. (this shouldn't occur though) */
1489*61046927SAndroid Build Coastguard Worker if (list->Parameters[first_param].Size !=
1490*61046927SAndroid Build Coastguard Worker _mesa_program_state_value_size(list->Parameters[first_param].StateIndexes))
1491*61046927SAndroid Build Coastguard Worker break;
1492*61046927SAndroid Build Coastguard Worker
1493*61046927SAndroid Build Coastguard Worker /* Search for light attributes that are adjacent in memory. */
1494*61046927SAndroid Build Coastguard Worker for (int i = first_param + 1; i < (int)list->NumParameters; i++) {
1495*61046927SAndroid Build Coastguard Worker if (list->Parameters[i].StateIndexes[0] == STATE_LIGHT &&
1496*61046927SAndroid Build Coastguard Worker /* Consecutive attributes of the same light: */
1497*61046927SAndroid Build Coastguard Worker ((list->Parameters[i].StateIndexes[1] ==
1498*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[1] &&
1499*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[2] ==
1500*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[2] + 1) ||
1501*61046927SAndroid Build Coastguard Worker /* Consecutive attributes between 2 lights: */
1502*61046927SAndroid Build Coastguard Worker /* SPOT_CUTOFF should have only 1 component, which isn't true
1503*61046927SAndroid Build Coastguard Worker * with unpacked uniform storage. */
1504*61046927SAndroid Build Coastguard Worker (consts->PackedDriverUniformStorage &&
1505*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[1] ==
1506*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[1] + 1 &&
1507*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[2] == STATE_AMBIENT &&
1508*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[2] == STATE_SPOT_CUTOFF))) {
1509*61046927SAndroid Build Coastguard Worker last_param = i;
1510*61046927SAndroid Build Coastguard Worker continue;
1511*61046927SAndroid Build Coastguard Worker }
1512*61046927SAndroid Build Coastguard Worker break; /* The adjacent state var is incompatible. */
1513*61046927SAndroid Build Coastguard Worker }
1514*61046927SAndroid Build Coastguard Worker if (last_param > first_param) {
1515*61046927SAndroid Build Coastguard Worker /* Convert the state var to STATE_LIGHT_ARRAY. */
1516*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[0] = STATE_LIGHT_ARRAY;
1517*61046927SAndroid Build Coastguard Worker /* Set the offset in floats. */
1518*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[1] =
1519*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[1] * /* light index */
1520*61046927SAndroid Build Coastguard Worker sizeof(struct gl_light_uniforms) / 4 +
1521*61046927SAndroid Build Coastguard Worker (list->Parameters[first_param].StateIndexes[2] - STATE_AMBIENT) * 4;
1522*61046927SAndroid Build Coastguard Worker
1523*61046927SAndroid Build Coastguard Worker /* Set the real size in floats that we will upload (memcpy). */
1524*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[2] =
1525*61046927SAndroid Build Coastguard Worker _mesa_program_state_value_size(list->Parameters[last_param].StateIndexes) +
1526*61046927SAndroid Build Coastguard Worker list->Parameters[last_param].ValueOffset -
1527*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].ValueOffset;
1528*61046927SAndroid Build Coastguard Worker
1529*61046927SAndroid Build Coastguard Worker /* Set the allocated size, which can be aligned to 4 components. */
1530*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].Size =
1531*61046927SAndroid Build Coastguard Worker list->Parameters[last_param].Size +
1532*61046927SAndroid Build Coastguard Worker list->Parameters[last_param].ValueOffset -
1533*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].ValueOffset;
1534*61046927SAndroid Build Coastguard Worker
1535*61046927SAndroid Build Coastguard Worker param_diff = last_param - first_param;
1536*61046927SAndroid Build Coastguard Worker break; /* all done */
1537*61046927SAndroid Build Coastguard Worker }
1538*61046927SAndroid Build Coastguard Worker
1539*61046927SAndroid Build Coastguard Worker /* We were not able to convert light attributes to STATE_LIGHT_ARRAY.
1540*61046927SAndroid Build Coastguard Worker * Another occuring pattern is light attentuation vectors placed back
1541*61046927SAndroid Build Coastguard Worker * to back. Find them.
1542*61046927SAndroid Build Coastguard Worker */
1543*61046927SAndroid Build Coastguard Worker if (list->Parameters[first_param].StateIndexes[2] == STATE_ATTENUATION) {
1544*61046927SAndroid Build Coastguard Worker for (int i = first_param + 1; i < (int)list->NumParameters; i++) {
1545*61046927SAndroid Build Coastguard Worker if (list->Parameters[i].StateIndexes[0] == STATE_LIGHT &&
1546*61046927SAndroid Build Coastguard Worker /* Consecutive light: */
1547*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[1] ==
1548*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[1] + 1 &&
1549*61046927SAndroid Build Coastguard Worker /* Same attribute: */
1550*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[2] ==
1551*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[2]) {
1552*61046927SAndroid Build Coastguard Worker last_param = i;
1553*61046927SAndroid Build Coastguard Worker continue;
1554*61046927SAndroid Build Coastguard Worker }
1555*61046927SAndroid Build Coastguard Worker break; /* The adjacent state var is incompatible. */
1556*61046927SAndroid Build Coastguard Worker }
1557*61046927SAndroid Build Coastguard Worker if (last_param > first_param) {
1558*61046927SAndroid Build Coastguard Worker param_diff = last_param - first_param;
1559*61046927SAndroid Build Coastguard Worker
1560*61046927SAndroid Build Coastguard Worker /* Convert the state var to STATE_LIGHT_ATTENUATION_ARRAY. */
1561*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[0] =
1562*61046927SAndroid Build Coastguard Worker STATE_LIGHT_ATTENUATION_ARRAY;
1563*61046927SAndroid Build Coastguard Worker /* Keep the light index the same. */
1564*61046927SAndroid Build Coastguard Worker /* Set the number of lights. */
1565*61046927SAndroid Build Coastguard Worker unsigned size = param_diff + 1;
1566*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[2] = size;
1567*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].Size = size * 4;
1568*61046927SAndroid Build Coastguard Worker break; /* all done */
1569*61046927SAndroid Build Coastguard Worker }
1570*61046927SAndroid Build Coastguard Worker }
1571*61046927SAndroid Build Coastguard Worker break;
1572*61046927SAndroid Build Coastguard Worker
1573*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_ENV:
1574*61046927SAndroid Build Coastguard Worker case STATE_VERTEX_PROGRAM_LOCAL:
1575*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_ENV:
1576*61046927SAndroid Build Coastguard Worker case STATE_FRAGMENT_PROGRAM_LOCAL:
1577*61046927SAndroid Build Coastguard Worker if (list->Parameters[first_param].Size != 4)
1578*61046927SAndroid Build Coastguard Worker break;
1579*61046927SAndroid Build Coastguard Worker
1580*61046927SAndroid Build Coastguard Worker /* Search for adjacent mergeable state vars. */
1581*61046927SAndroid Build Coastguard Worker for (int i = first_param + 1; i < (int)list->NumParameters; i++) {
1582*61046927SAndroid Build Coastguard Worker if (list->Parameters[i].StateIndexes[0] ==
1583*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[0] &&
1584*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[1] ==
1585*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[1] + 1 &&
1586*61046927SAndroid Build Coastguard Worker list->Parameters[i].Size == 4) {
1587*61046927SAndroid Build Coastguard Worker last_param = i;
1588*61046927SAndroid Build Coastguard Worker continue;
1589*61046927SAndroid Build Coastguard Worker }
1590*61046927SAndroid Build Coastguard Worker break; /* The adjacent state var is incompatible. */
1591*61046927SAndroid Build Coastguard Worker }
1592*61046927SAndroid Build Coastguard Worker if (last_param > first_param) {
1593*61046927SAndroid Build Coastguard Worker /* Set STATE_xxx_RANGE. */
1594*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_VERTEX_PROGRAM_ENV + 1 ==
1595*61046927SAndroid Build Coastguard Worker STATE_VERTEX_PROGRAM_ENV_ARRAY);
1596*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_VERTEX_PROGRAM_LOCAL + 1 ==
1597*61046927SAndroid Build Coastguard Worker STATE_VERTEX_PROGRAM_LOCAL_ARRAY);
1598*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_FRAGMENT_PROGRAM_ENV + 1 ==
1599*61046927SAndroid Build Coastguard Worker STATE_FRAGMENT_PROGRAM_ENV_ARRAY);
1600*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_FRAGMENT_PROGRAM_LOCAL + 1 ==
1601*61046927SAndroid Build Coastguard Worker STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY);
1602*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[0]++;
1603*61046927SAndroid Build Coastguard Worker
1604*61046927SAndroid Build Coastguard Worker param_diff = last_param - first_param;
1605*61046927SAndroid Build Coastguard Worker
1606*61046927SAndroid Build Coastguard Worker /* Set the size. */
1607*61046927SAndroid Build Coastguard Worker unsigned size = param_diff + 1;
1608*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[2] = size;
1609*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].Size = size * 4;
1610*61046927SAndroid Build Coastguard Worker }
1611*61046927SAndroid Build Coastguard Worker break;
1612*61046927SAndroid Build Coastguard Worker
1613*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD: {
1614*61046927SAndroid Build Coastguard Worker if (list->Parameters[first_param].Size != 4)
1615*61046927SAndroid Build Coastguard Worker break;
1616*61046927SAndroid Build Coastguard Worker
1617*61046927SAndroid Build Coastguard Worker gl_state_index16 state = STATE_NOT_STATE_VAR;
1618*61046927SAndroid Build Coastguard Worker unsigned num_lights = 0;
1619*61046927SAndroid Build Coastguard Worker
1620*61046927SAndroid Build Coastguard Worker for (gl_state_index state_iter = STATE_LIGHTPROD_ARRAY_FRONT;
1621*61046927SAndroid Build Coastguard Worker state_iter <= STATE_LIGHTPROD_ARRAY_TWOSIDE; state_iter++) {
1622*61046927SAndroid Build Coastguard Worker unsigned num_attribs, base_attrib, attrib_incr;
1623*61046927SAndroid Build Coastguard Worker
1624*61046927SAndroid Build Coastguard Worker switch (state_iter) {
1625*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_FRONT:
1626*61046927SAndroid Build Coastguard Worker num_attribs = 3;
1627*61046927SAndroid Build Coastguard Worker base_attrib = MAT_ATTRIB_FRONT_AMBIENT;
1628*61046927SAndroid Build Coastguard Worker attrib_incr = 2;
1629*61046927SAndroid Build Coastguard Worker break;
1630*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_BACK:
1631*61046927SAndroid Build Coastguard Worker num_attribs = 3;
1632*61046927SAndroid Build Coastguard Worker base_attrib = MAT_ATTRIB_BACK_AMBIENT;
1633*61046927SAndroid Build Coastguard Worker attrib_incr = 2;
1634*61046927SAndroid Build Coastguard Worker break;
1635*61046927SAndroid Build Coastguard Worker case STATE_LIGHTPROD_ARRAY_TWOSIDE:
1636*61046927SAndroid Build Coastguard Worker num_attribs = 6;
1637*61046927SAndroid Build Coastguard Worker base_attrib = MAT_ATTRIB_FRONT_AMBIENT;
1638*61046927SAndroid Build Coastguard Worker attrib_incr = 1;
1639*61046927SAndroid Build Coastguard Worker break;
1640*61046927SAndroid Build Coastguard Worker default:
1641*61046927SAndroid Build Coastguard Worker unreachable("unexpected state-var");
1642*61046927SAndroid Build Coastguard Worker }
1643*61046927SAndroid Build Coastguard Worker
1644*61046927SAndroid Build Coastguard Worker /* Find all attributes for one light. */
1645*61046927SAndroid Build Coastguard Worker while (first_param + (num_lights + 1) * num_attribs <=
1646*61046927SAndroid Build Coastguard Worker list->NumParameters &&
1647*61046927SAndroid Build Coastguard Worker (state == STATE_NOT_STATE_VAR || state == state_iter)) {
1648*61046927SAndroid Build Coastguard Worker unsigned i = 0, base = first_param + num_lights * num_attribs;
1649*61046927SAndroid Build Coastguard Worker
1650*61046927SAndroid Build Coastguard Worker /* Consecutive light indices: */
1651*61046927SAndroid Build Coastguard Worker if (list->Parameters[first_param].StateIndexes[1] + num_lights ==
1652*61046927SAndroid Build Coastguard Worker list->Parameters[base].StateIndexes[1]) {
1653*61046927SAndroid Build Coastguard Worker for (i = 0; i < num_attribs; i++) {
1654*61046927SAndroid Build Coastguard Worker if (list->Parameters[base + i].StateIndexes[0] ==
1655*61046927SAndroid Build Coastguard Worker STATE_LIGHTPROD &&
1656*61046927SAndroid Build Coastguard Worker list->Parameters[base + i].Size == 4 &&
1657*61046927SAndroid Build Coastguard Worker /* Equal light indices: */
1658*61046927SAndroid Build Coastguard Worker list->Parameters[base + i].StateIndexes[1] ==
1659*61046927SAndroid Build Coastguard Worker list->Parameters[base + 0].StateIndexes[1] &&
1660*61046927SAndroid Build Coastguard Worker /* Consecutive attributes: */
1661*61046927SAndroid Build Coastguard Worker list->Parameters[base + i].StateIndexes[2] ==
1662*61046927SAndroid Build Coastguard Worker base_attrib + i * attrib_incr)
1663*61046927SAndroid Build Coastguard Worker continue;
1664*61046927SAndroid Build Coastguard Worker break;
1665*61046927SAndroid Build Coastguard Worker }
1666*61046927SAndroid Build Coastguard Worker }
1667*61046927SAndroid Build Coastguard Worker if (i == num_attribs) {
1668*61046927SAndroid Build Coastguard Worker /* Accept all parameters for merging. */
1669*61046927SAndroid Build Coastguard Worker state = state_iter;
1670*61046927SAndroid Build Coastguard Worker last_param = base + num_attribs - 1;
1671*61046927SAndroid Build Coastguard Worker num_lights++;
1672*61046927SAndroid Build Coastguard Worker } else {
1673*61046927SAndroid Build Coastguard Worker break;
1674*61046927SAndroid Build Coastguard Worker }
1675*61046927SAndroid Build Coastguard Worker }
1676*61046927SAndroid Build Coastguard Worker }
1677*61046927SAndroid Build Coastguard Worker
1678*61046927SAndroid Build Coastguard Worker if (last_param > first_param) {
1679*61046927SAndroid Build Coastguard Worker param_diff = last_param - first_param;
1680*61046927SAndroid Build Coastguard Worker
1681*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[0] = state;
1682*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[2] = num_lights;
1683*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].Size = (param_diff + 1) * 4;
1684*61046927SAndroid Build Coastguard Worker }
1685*61046927SAndroid Build Coastguard Worker break;
1686*61046927SAndroid Build Coastguard Worker }
1687*61046927SAndroid Build Coastguard Worker
1688*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION:
1689*61046927SAndroid Build Coastguard Worker case STATE_LIGHT_POSITION_NORMALIZED:
1690*61046927SAndroid Build Coastguard Worker if (list->Parameters[first_param].Size != 4)
1691*61046927SAndroid Build Coastguard Worker break;
1692*61046927SAndroid Build Coastguard Worker
1693*61046927SAndroid Build Coastguard Worker for (int i = first_param + 1; i < (int)list->NumParameters; i++) {
1694*61046927SAndroid Build Coastguard Worker if (list->Parameters[i].StateIndexes[0] ==
1695*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[0] &&
1696*61046927SAndroid Build Coastguard Worker /* Consecutive light: */
1697*61046927SAndroid Build Coastguard Worker list->Parameters[i].StateIndexes[1] ==
1698*61046927SAndroid Build Coastguard Worker list->Parameters[i - 1].StateIndexes[1] + 1) {
1699*61046927SAndroid Build Coastguard Worker last_param = i;
1700*61046927SAndroid Build Coastguard Worker continue;
1701*61046927SAndroid Build Coastguard Worker }
1702*61046927SAndroid Build Coastguard Worker break; /* The adjacent state var is incompatible. */
1703*61046927SAndroid Build Coastguard Worker }
1704*61046927SAndroid Build Coastguard Worker if (last_param > first_param) {
1705*61046927SAndroid Build Coastguard Worker param_diff = last_param - first_param;
1706*61046927SAndroid Build Coastguard Worker
1707*61046927SAndroid Build Coastguard Worker /* Convert the state var to STATE_LIGHT_POSITION_*ARRAY. */
1708*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_LIGHT_POSITION + 1 ==
1709*61046927SAndroid Build Coastguard Worker STATE_LIGHT_POSITION_ARRAY);
1710*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(STATE_LIGHT_POSITION_NORMALIZED + 1 ==
1711*61046927SAndroid Build Coastguard Worker STATE_LIGHT_POSITION_NORMALIZED_ARRAY);
1712*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[0]++;
1713*61046927SAndroid Build Coastguard Worker /* Keep the light index the same. */
1714*61046927SAndroid Build Coastguard Worker unsigned size = param_diff + 1;
1715*61046927SAndroid Build Coastguard Worker /* Set the number of lights. */
1716*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].StateIndexes[2] = size;
1717*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].Size = size * 4;
1718*61046927SAndroid Build Coastguard Worker }
1719*61046927SAndroid Build Coastguard Worker }
1720*61046927SAndroid Build Coastguard Worker
1721*61046927SAndroid Build Coastguard Worker if (param_diff) {
1722*61046927SAndroid Build Coastguard Worker /* Update the name. */
1723*61046927SAndroid Build Coastguard Worker free((void*)list->Parameters[first_param].Name);
1724*61046927SAndroid Build Coastguard Worker list->Parameters[first_param].Name =
1725*61046927SAndroid Build Coastguard Worker _mesa_program_state_string(list->Parameters[first_param].StateIndexes);
1726*61046927SAndroid Build Coastguard Worker
1727*61046927SAndroid Build Coastguard Worker /* Free names that we are going to overwrite. */
1728*61046927SAndroid Build Coastguard Worker for (int i = first_param + 1; i <= last_param; i++)
1729*61046927SAndroid Build Coastguard Worker free((char*)list->Parameters[i].Name);
1730*61046927SAndroid Build Coastguard Worker
1731*61046927SAndroid Build Coastguard Worker /* Remove the merged state vars. */
1732*61046927SAndroid Build Coastguard Worker if (last_param + 1 < list->NumParameters) {
1733*61046927SAndroid Build Coastguard Worker memmove(&list->Parameters[first_param + 1],
1734*61046927SAndroid Build Coastguard Worker &list->Parameters[last_param + 1],
1735*61046927SAndroid Build Coastguard Worker sizeof(list->Parameters[0]) *
1736*61046927SAndroid Build Coastguard Worker (list->NumParameters - last_param - 1));
1737*61046927SAndroid Build Coastguard Worker }
1738*61046927SAndroid Build Coastguard Worker list->NumParameters -= param_diff;
1739*61046927SAndroid Build Coastguard Worker }
1740*61046927SAndroid Build Coastguard Worker }
1741*61046927SAndroid Build Coastguard Worker
1742*61046927SAndroid Build Coastguard Worker _mesa_recompute_parameter_bounds(list);
1743*61046927SAndroid Build Coastguard Worker }
1744